传送门::http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:有n个连在一起的地道,接下来m个操作,D x 代表摧毁 x 地道;R 代表修建最近一次摧毁的地道;R x 查询与x地道相连的地道有多少个(最大连续区间长度)
思路::线段树
线段树区间合并问题,维护三个变量
llen ::从左端点开始的最大连续区间长度
rlen::从右端点开始的最大连续区间长度
mlen::该区间的最大连续长度
如何维护呢?
双亲的llen 如果它左孩子的整个区间连续,llen=左孩子llen+右孩子的llen
双亲的rlen 如何它右孩子的整个区间来连续,rlen=右孩子rlen+左孩子的rlen
双亲的mlen 左孩子的mlen,右孩子的mlen,左孩子的rlen+右孩子的llen 三者最大值
至于查询的话也比较简单
如果它在左孩子rlen中,结果就是左孩子derlen+右孩子的llen,反之就在左孩子里
如果他在右孩子的llen中,结果就是右孩子的llen+左孩子的rllen反之就在右孩子里
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn=5e4+5; 5 6 int llen[maxn<<2],rlen[maxn<<2],mlen[maxn<<2]; 7 8 stack<int>s; 9 10 void pushup(int rt,int m) 11 { 12 mlen[rt]=max(max(mlen[2*rt],mlen[2*rt+1]),rlen[2*rt]+llen[2*rt+1]); 13 llen[rt]=llen[2*rt]; 14 rlen[rt]=rlen[2*rt+1]; 15 if(llen[2*rt]==m-(m>>1)) 16 llen[rt]+=llen[2*rt+1]; 17 if(rlen[2*rt+1]==(m>>1)) 18 rlen[rt]+=rlen[2*rt]; 19 } 20 void build(int l,int r,int rt) 21 { 22 llen[rt]=rlen[rt]=mlen[rt]=r-l+1; 23 if(l==r){return ;} 24 int mid=(l+r)>>1; 25 build(l,mid,2*rt); 26 build(mid+1,r,2*rt+1); 27 } 28 void update(int l,int r,int rt,int pos,int k) 29 { 30 if(l==r){ 31 llen[rt]=rlen[rt]=mlen[rt]=k; 32 return ; 33 } 34 int mid=(l+r)>>1; 35 if(pos<=mid) 36 update(l,mid,2*rt,pos,k); 37 else 38 update(mid+1,r,2*rt+1,pos,k); 39 pushup(rt,r-l+1); 40 } 41 int query(int l,int r,int rt,int pos) 42 { 43 if(mlen[rt]==0||mlen[rt]==(r-l+1)){ 44 return mlen[rt]; 45 } 46 int mid=(l+r)>>1; 47 if(pos<=mid){ 48 if(pos>=mid-rlen[2*rt]+1) 49 return rlen[2*rt]+llen[2*rt+1]; 50 else 51 return query(l,mid,2*rt,pos); 52 } 53 else{ 54 if(pos<=mid+llen[2*rt+1]) 55 return llen[2*rt+1]+rlen[2*rt]; 56 else 57 return query(mid+1,r,2*rt+1,pos); 58 } 59 } 60 int main() 61 { 62 int n,m; 63 while(~scanf("%d%d",&n,&m)){ 64 build(1,n,1); 65 while(m--) 66 { 67 char op;int k; 68 scanf(" %c",&op); 69 if(op=='R'&&!s.empty()){ 70 update(1,n,1,s.top(),1); 71 s.pop(); 72 } 73 else if(op=='D'){ 74 scanf("%d",&k); 75 s.push(k); 76 update(1,n,1,k,0); 77 } 78 else { 79 scanf("%d",&k); 80 printf("%d\n",query(1,n,1,k)); 81 } 82 } 83 } 84 return 0; 85 }