1. 程式人生 > >2018年湖南省省賽 H題-千萬不要用樹套樹

2018年湖南省省賽 H題-千萬不要用樹套樹

amp pan bsp 賽後 can 湖南省 提醒 algorithm spa

不要被題目給誤導,這題根本不用樹套樹(我也不會),用線段樹就可以完美解決。。。

比賽時也想到用線段樹,但是想的太簡單了,於是連wa兩發。。然後一直到比賽結束也沒有

想到正確思路,說到底我的線段樹還是太菜了啊,感覺這題對線段樹水平的要求比我的水平高了

兩個等級,許老師的線段樹水平比我高了至少三個等級,所以沒費多大力就想到了正確思路。。

賽後許老師提醒了我幾個關鍵點,發現這題只要構思好了其實並不是很難啊。,唉。。上代碼:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using
namespace std; int sumv1[400005],sumv2[400005],cnt[400005]; int T,n,q,c,p,ql,qr,p1,ql1,qr1,x,y; void update1(int o,int l,int r){ int m=(l+r)/2; if(l==r)sumv1[o]+=1; else{ if(p<=m)update1(o*2,l,m); else update1(o*2+1,m+1,r); sumv1[o]=sumv1[o*2]+sumv1[o*2+1]; } } int query1(int
o,int l,int r){ int m=(l+r)/2; if(l>=ql&&r<=qr)return sumv1[o]; int ans=0; if(ql<=m)ans+=query1(o*2,l,m); if(qr>m)ans+=query1(o*2+1,m+1,r); return ans; } void update2(int o,int l,int r){ int m=(l+r)/2; if(l==r)sumv2[o]+=1; else{ if(p1<=m)update2(o*2
,l,m); else update2(o*2+1,m+1,r); sumv2[o]=sumv2[o*2]+sumv2[o*2+1]; } } int query2(int o,int l,int r){ int m=(l+r)/2; if(l>=ql1&&r<=qr1)return sumv2[o]; int ans=0; if(ql1<=m)ans+=query2(o*2,l,m); if(qr1>m)ans+=query2(o*2+1,m+1,r); return ans; } int main(){ while(~scanf("%d%d",&n,&q)){ for(int i=0;i<=n*4;i++){ sumv1[i]=sumv2[i]=cnt[i]=0; } int s=0; while(q--){ scanf("%d",&c); if(c==1){ scanf("%d%d",&p,&p1); if(p==p1)cnt[p]++; update1(1,1,n); update2(1,1,n); s++; } else{ scanf("%d%d",&x,&y); ql=x+1,qr=n; ql1=1,qr1=y-1; int ans=s; if(qr>=ql)ans-=query1(1,1,n); if(qr1>=ql1)ans-=query2(1,1,n); if(y-x==2)ans+=cnt[x+1]; printf("%d\n",ans); } } } }

2018年湖南省省賽 H題-千萬不要用樹套樹