题目链接:
题目解析:
听说是平衡树的题(然鹅我是在线段树树状数组分类里找到的它)
线段树做法:把题目看成一个仅实现区间修改的线段树,用tagtag数组打打标记即可
有空补一下平衡树树状数组做法吧…好像还有一个神奇的STL做法?
翻译:一定不咕一定不咕
AC代码(线段树):
#include<cstdio>
#define N 100200
#define ls i<<1
#define rs i<<1|1
int min(int a,int b) {return a>b?b:a;}
int max(int a,int b) {return a>b?a:b;}
struct data{
int cnt,ml,mr,lc,rc;
data operator + (const data &b) {return (data){(cnt&&b.cnt)?cnt+b.cnt-(rc&&(rc==b.lc)):cnt+b.cnt,min(ml,b.ml),max(mr,b.mr),lc,b.rc};}
void clear() {ml=mr=lc=rc=cnt=-1;}
};
struct segmenttree{
data tree[N<<3],tag[N<<3];
void pushdown(int i)
{
if (!~tag[i].cnt) return;
tree[ls].lc=tree[ls].rc=tree[rs].lc=tree[rs].rc=tag[i].cnt;
if (tag[i].cnt)
{
tree[rs].cnt=tree[ls].cnt=1;
tree[rs].ml=tree[ls].ml=tag[i].ml;
tree[rs].mr=tree[ls].mr=tag[i].mr;
tag[ls]=tag[rs]=tag[i];
}
else
{
int mid=(tag[i].ml+tag[i].mr)>>1;
tree[rs].cnt=tree[ls].cnt=0;
tree[ls].ml=tag[i].ml;
tree[rs].ml=mid+1;
tree[rs].mr=tag[i].mr;
tree[ls].mr=mid;
tag[ls]=tag[rs]=tag[i];
tag[ls].mr=mid;tag[rs].ml=mid+1;
}
tag[i].clear();
}
void update(int i,int l,int r,int L,int R,int c)
{
if (L<=l&&r<=R)
{
tree[i].lc=tree[i].rc=c;
tag[i].cnt=c;
if (c)
{
tree[i].cnt=1;
tree[i].ml=L;tree[i].mr=R;
tag[i].ml=L;tag[i].mr=R;
}
else
{
tree[i].cnt=0;
tree[i].ml=l;tree[i].mr=r;
tag[i].ml=l;tag[i].mr=r;
}
return;
}
int mid=(l+r)>>1;
pushdown(i);
if (L<=mid) update(ls,l,mid,L,R,c);
if (mid<R) update(rs,mid+1,r,L,R,c);
tree[i]=tree[ls]+tree[rs];
}
data query(int i,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return tree[i];
pushdown(i);
int mid=(l+r)>>1;
if (mid<L) return query(rs,mid+1,r,L,R);
if (mid>=R) return query(ls,l,mid,L,R);
return query(ls,l,mid,L,mid)+query(rs,mid+1,r,mid+1,R);
}
void build(int i,int l,int r)
{
tag[i].clear();
if (l==r)
{
tree[i].cnt=0;
tree[i].lc=tree[i].rc=0;
tree[i].ml=tree[i].mr=l;
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);build(rs,mid+1,r);
tree[i]=tree[ls]+tree[rs];
}
}cof;
int main()
{
int n,l,r;char a;
scanf("%d",&n);
cof.build(1,1,100000);
while(n--)
{
while(a=getchar()) if (a=='A'||a=='B') break;
if (a=='A')
{
scanf("%d%d",&l,&r);
data tmp=cof.query(1,1,100000,l,r);
printf("%d\n",tmp.cnt);
cof.update(1,1,100000,tmp.ml,tmp.mr,0);
cof.update(1,1,100000,l,r,n);
}
else
{
data tmp=cof.query(1,1,100000,1,100000);
printf("%d\n",tmp.cnt);
}
}
return 0;
}