您的位置:首页 > 其它

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

2016-08-15 17:20 405 查看
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 50010
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  杭电1540