题目链接:1540 Tunnel Warfare
以为单组输入 这个题多组输入
结构体记录每个区间左边和右边的连续区间 ms记录最大
在查询操作时:
1、这个点即将查询到右区间 看这个点 x 是否存在于右区间的ls 如果存在说明有可能 左区间的rs 和右区间的 ls 是连续的 这时候我们要考虑查询两个区间并且 值想加
查询 左区间的时候同理
#include<bits/stdc++.h> using namespace std; #define maxn 500010 struct ac{ int ls,rs,ms; }a[maxn]; int b[maxn]; void build(int l,int r,int in){ if(l==r){ a[in].ls=a[in].rs=a[in].ms=1; return ; } int mid=(l+r)/2; build(l,mid,in*2); build(mid+1,r,in*2+1); a[in].ms=a[in].ls=a[in].rs=(a[in*2].ms+a[in*2+1].ms); } void updata(int l,int r,int in,int z,int i){ if(l==r){ if(i>0){ a[in].ls=a[in].rs=a[in].ms=1; }else{ a[in].ls=a[in].rs=a[in].ms=0; } return ; } int mid=(l+r)/2; if(z>mid){ updata(mid+1,r,in*2+1,z,i); }else updata(l,mid,in*2,z,i); int ll=in*2,rr=in*2+1; a[in].ls=a[ll].ls; a[in].rs=a[rr].rs; a[in].ms=max(a[ll].ms,max(a[rr].ms,a[ll].rs+a[rr].ls)); if(a[ll].ls==(mid-l+1)){ a[in].ls+=a[rr].ls; } if(a[rr].rs==(r-mid)){ a[in].rs+=a[ll].rs; } } int query(int l,int r,int in,int z){ if((a[in].ms==(r-l+1))||(a[in].ms==0)||(l==r)){ return a[in].ms; } int mid=(l+r)/2; if(z>mid){ if(z<=mid+a[in*2+1].ls){ return query(mid+1,r,in*2+1,z)+query(l,mid,in*2,mid); }else return query(mid+1,r,in*2+1,z); }else{ if(z>=mid-a[in*2].rs+1){ return query(l,mid,in*2,z)+query(mid+1,r,in*2+1,mid+1); }else return query(l,mid,in*2,z); } } int main(){ int n,m; while(cin>>n>>m){ build(1,n,1); int len=0; for(int j=0;j<m;j++){ char c[10]; int x; cin>>c; if(c[0]=='D'){ cin>>x; b[++len]=x; updata(1,n,1,x,0); }else if(c[0]=='R'){ if(len-1>=0) updata(1,n,1,b[len--],1); }else{ cin>>x; cout<<query(1,n,1,x)<<endl; } } } }