E - Tunnel Warfare HDU - 1540
区间合并+单点修改,查询最大连续长度
区间修改的线段树实现起来稍微比较麻烦,因为维护两个区间左右延伸的数组。
每次查询的时候,如果该区间是sum[rt]||l==r||sum[rt]==r-l+1,那么返回,否则继续向下查找,因为是单点修改,每次修改都要到最底层,所以懒标记不起作用,其他的就是代码实现的问题了。
1 #include <iostream> 2 #include <stack> 3 #include <algorithm> 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 using namespace std; 7 8 const int maxn=5e4+5; 9 int sum[maxn<<3],lsum[maxn<<3],rsum[maxn<<3]; 10 11 //建树 12 void build(int l,int r,int rt){ 13 if(l==r) 14 { 15 sum[rt]=lsum[rt]=rsum[rt]=1; 16 return ; 17 } 18 sum[rt]=lsum[rt]=rsum[rt]=r-l+1; 19 int m=(l+r)>>1; 20 build(lson); 21 build(rson); 22 } 23 24 void pushup(int rt,int len){ 25 lsum[rt]=lsum[rt<<1]; 26 rsum[rt]=rsum[rt<<1|1]; 27 if(lsum[rt]==len-(len>>1)) lsum[rt]+=lsum[rt<<1|1]; 28 /*if(rt==2) 29 cout <<"rt="<<rt<<" "<<(len<<1)<<endl;*/ 30 if(rsum[rt]==len>>1) rsum[rt]+=rsum[rt<<1]; 31 sum[rt]=max(max(sum[rt<<1],sum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]); 32 } 33 34 //更新 35 void update(int p,int x,int l,int r,int rt){ 36 if(p==l&&p==r){ 37 if(x==0){ 38 sum[rt]=lsum[rt]=rsum[rt]=0; 39 }else 40 sum[rt]=lsum[rt]=rsum[rt]=1; 41 //cout << "genshi"<<rt<<" "<<p<<endl; 42 return; 43 } 44 int m=(l+r)>>1; 45 if(p<=m) update(p,x,lson); 46 else update(p,x,rson); 47 pushup(rt,r-l+1); 48 } 49 50 //查询 51 int query(int p,int l,int r,int rt){ 52 if(sum[rt]==r-l+1||l==r||sum[rt]==0){ 53 return sum[rt]; 54 } 55 int m=(l+r)>>1; 56 if(p<=m) 57 { 58 if(p>=m-rsum[rt<<1]+1) return query(p,lson)+query(m+1,rson); 59 else return query(p,lson); 60 } 61 else{ 62 if(p<=m+lsum[rt<<1|1]) return query(p,rson)+query(m,lson); 63 else return query(p,rson); 64 } 65 } 66 67 68 69 70 int main(){ 71 int n,m; 72 std::ios::sync_with_stdio(false); 73 while(cin>>n>>m) 74 { 75 76 77 build(1,n,1); 78 /*for(int i=1;i<=20;i++) 79 { 80 cout << i<<" "<<sum[i]<<endl; 81 } */ 82 //cout <<"*****************\n"; 83 stack <int> S; 84 char c[3]; 85 while(m--){ 86 cin>>c; 87 if(c[0]=='D') { 88 int x;cin>>x; 89 S.push(x); 90 update(x,0,1,n,1); 91 /* for(int i=1;i<=20;i++) 92 { 93 cout << i<<" "<<sum[i]<<" "<<lsum[i]<<" "<<rsum[i]<<endl; 94 } */ 95 }else if(c[0]=='R'){ 96 int x;x=S.top(); 97 //cout <<x<<endl; 98 update(x,1,1,n,1); 99 S.pop(); 100 /*for(int i=1;i<=20;i++) 101 { 102 cout << i<<" "<<sum[i]<<endl; 103 } */ 104 }else{ 105 int x;cin>>x; 106 cout <<query(x,1,n,1)<<"\n"; 107 } 108 } 109 } 110 return 0; 111 }