题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540
这个题目是个区间合并的模板题,但是有一点不同的是分两步查询思路很清晰;
这里有一个博客写的不错,我就不再赘述了;链接:http://blog.csdn.net/xingyeyongheng/article/details/11619461
#include #include #include #include #include #include #include #include #include #include #include #define LL long long #define inf 1<<30 #define s(a,b) scanf("%d%d",&a,&b) #define Clear(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=50015; int n,m,a,b,ch; int num[N]; // 该数组记录被损坏的村庄; int ls[N<<2],rs[N<<2]; // 分别存左右端点起的最大长度; void PushUp(int rt,int m) { ls[rt]=ls[rt<<1]; rs[rt]=rs[rt<<1|1]; if(ls[rt]==m-(m>>1)) ls[rt]+=ls[rt<<1|1]; // 左儿子区间最大长度为整个区间,需要拼接右儿子区间左端点起的最长长度; if(rs[rt]==m>>1) rs[rt]+=rs[rt<<1]; // 右儿子区间最大长度为整个区间,同理; } void Build(int l,int r,int rt) { ls[rt]=rs[rt]=r-l+1; // 初始化为最长长度; if(l!=r){ int mid=(l+r)>>1; Build(l,mid,rt<<1); Build(mid+1,r,rt<<1|1); } } void Updata(int p,int v,int l,int r,int rt) { if(l==r){ ls[rt]=v; rs[rt]=v; return; } int mid=(l+r)>>1; if(p<=mid) Updata(p,v,l,mid,rt<<1); else Updata(p,v,mid+1,r,rt<<1|1); PushUp(rt,r-l+1); } int QueryL(int L,int R,int l,int r,int rt) // 返回右边左区间最大长度; { if(L<=l&&r<=R) return ls[rt]; int mid=(l+r)>>1; if(R<=mid) return QueryL(L,R,l,mid,rt<<1); else if(L>mid) return QueryL(L,R,mid+1,r,rt<<1|1); else{ int lans=QueryL(L,mid,l,mid,rt<<1); int rans=QueryL(mid+1,R,mid+1,r,rt<<1|1); if(lans==mid-L+1) return lans+rans; else return lans; } } int QueryR(int L,int R,int l,int r,int rt) // 返回左边右区间最大长度; { if(L<=l&&r<=R) return rs[rt]; int mid=(l+r)>>1; if(R<=mid) return QueryR(L,R,l,mid,rt<<1); else if(L>mid) return QueryR(L,R,mid+1,r,rt<<1|1); else{ int lans=QueryR(L,mid,l,mid,rt<<1); int rans=QueryR(mid+1,R,mid+1,r,rt<<1|1); if(rans==R-mid) return lans+rans; return rans; } } int main() { //freopen("../../in.txt","r",stdin); //freopen("../../out.txt","w",stdout); while(~s(n,m)){ Build(1,n,1); int top=0; while(m--){ scanf(" %c",&ch); if(ch=='D'){ scanf("%d",&a); num[top++]=a; Updata(a,0,1,n,1); }else if(ch=='R'&&top>0){ // top>0说明还有被损坏的村庄; int a=num[--top]; Updata(a,1,1,n,1); }else if(ch=='Q'){ scanf("%d",&a); int ans=QueryL(a,n,1,n,1)+QueryR(1,a,1,n,1); printf("%d\n",ans>0?ans-1:0); } } } return 0; }