线段树区间合并模板-杭电1540

来源:互联网 发布:科技网络报修电话 编辑:程序博客网 时间:2024/06/05 02:17
#include <iostream>#include <cstdio>#include <cstring>#define maxn 50010using namespace std;struct {int l;//记录左边界 int r;//记录右边界 int rl,ll,ml; //左边开始的最大连续长度,//以及右边开始的连续最大长度,还有整个区间的最大连续长度 }SegTree[maxn<<2];int que[50010];void build(int L,int R,int rt){SegTree[rt].ll=SegTree[rt].rl=SegTree[rt].ml=R-L+1;SegTree[rt].l=L;SegTree[rt].r=R;if(L==R)return;int m=(L+R)/2;build(L,m,rt<<1);build(m+1,R,rt<<1|1);}void update(int rt,int x,int val){if(SegTree[rt].r==SegTree[rt].l){if(val==0){SegTree[rt].ll=SegTree[rt].rl=SegTree[rt].ml=0;}else SegTree[rt].ll=SegTree[rt].rl=SegTree[rt].ml=1;return;}int m=(SegTree[rt].r+SegTree[rt].l)/2;if(x<=m)update(rt<<1,x,val);else update(rt<<1|1,x,val);SegTree[rt].ll=SegTree[rt<<1].ll;SegTree[rt].rl=SegTree[rt<<1|1].rl;SegTree[rt].ml=max(SegTree[rt<<1].ml,SegTree[rt<<1|1].ml);SegTree[rt].ml=max(SegTree[rt].ml,SegTree[rt<<1].rl+SegTree[rt<<1|1].ll);if(SegTree[rt<<1].ll==(SegTree[rt<<1].r-SegTree[rt<<1].l+1))SegTree[rt].ll+=SegTree[rt<<1|1].ll;if(SegTree[rt<<1|1].rl==(SegTree[rt<<1|1].r-SegTree[rt<<1|1].l+1))SegTree[rt].rl+=SegTree[rt<<1].rl;}int Query(int rt,int x){if(SegTree[rt].r==SegTree[rt].l||SegTree[rt].ml==0||SegTree[rt].ml==SegTree[rt].r-SegTree[rt].l+1){return SegTree[rt].ml;}int m=(SegTree[rt].r+SegTree[rt].l)/2;if(x<=m){if(SegTree[rt<<1].r-SegTree[rt<<1].rl+1<=x)return Query(rt<<1,x)+Query(rt<<1|1,m+1); else return Query(rt<<1,x);}else {if(SegTree[rt<<1|1].l+SegTree[rt<<1|1].ll-1>=x){return Query(rt<<1|1,x)+Query(rt<<1,m);}else return Query(rt<<1|1,x);}}int main(){int n,m,i,j,num,sum;char op[2];while(~scanf("%d%d",&n,&m)){sum=0;build(1,n,1);for(i=1;i<=m;i++){scanf("%s",op);if(op[0]=='D'){scanf("%d",&num);que[sum++]=num;update(1,num,0);}else if(op[0]=='R'){update(1,que[--sum],1);}else{scanf("%d",&num);printf("%d\n",Query(1,num));}}}return 0;}

0 0
原创粉丝点击