Description
由3种类型操作:
1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]
2)C i (1-base) 删除第i条增加的线段,保证每条插入线段最多插入一次,且这次删除操作一定合法
3) Q L R(1 <= L <= R <= 1000000000) 查询目前存在的线段中有多少条线段完全包含[L,R]这个线段,线段X被线段Y完全包含即LY <= LX
<= RX <= RY)
Input
多组数据,每组数据N
接下来N行,每行是三种操作之一(1 <= N <= 10^5)
Output
对于每个Q操作,输出一行,答案
Sample Input
6
D 1 100
D 3 8
D 4 10
Q 3 8
C 1
Q 3 8
Sample Output
2
1
Solution
CDQ分治,将删除操作看作插入一条数量为-1的线段,查询操作看作插入一条数量为0的线段,用cnt[i]表示第i次插入的线段被之前插入的线段包含的次数,按操作顺序进行分治,每次统计[l,mid+1]中有多少元素j满足j.y>=i.y,j.x<=i.x,其中mid+1<=i<=r,这个过程可以通过对两个区间都以x为第一关键字降序排,以y为第二关键字升序排,对于[mid+1,r]中的每个i(i为数量为0的元素,即为查询),将[l,mid]中所有满足j.y>=i.y的j以j.x为下标,cnt[j]为键值插入到树状数组中,那么每次只需统计树状数组中下标小于等于i.x的元素键值之和累加到cnt[i]中即可
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 222222
int n,h[maxn],tot;
struct node
{
int x,y,cnt,id,ans;
bool operator <(const node &a)const
{
if(y!=a.y)return y>a.y;
return x<a.x;
}
}p[maxn],q[maxn];
int cmpid(node a,node b)
{
return a.id<b.id;
}
struct BIT
{
#define lowbit(x) (x&(-x))
int b[maxn];
void init()
{
memset(b,0,sizeof(b));
}
void update(int x,int v)
{
while(x<=tot)
{
b[x]+=v;
x+=lowbit(x);
}
}
int query(int x)
{
int ans=0;
while(x)
{
ans+=b[x];
x-=lowbit(x);
}
return ans;
}
}bit;
void CDQ(int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
CDQ(l,mid);
CDQ(mid+1,r);
sort(p+l,p+mid+1);
sort(p+mid+1,p+r+1);
int j=l;
for(int i=mid+1;i<=r;i++)
{
for(;j<=mid&&p[j].y>=p[i].y;j++)
bit.update(p[j].x,p[j].cnt);
if(!p[i].cnt)p[i].ans+=bit.query(p[i].x);
}
for(int i=l;i<j;i++)bit.update(p[i].x,-p[i].cnt);
merge(p+l,p+mid+1,p+mid+1,p+r+1,q);
for(int i=0;i<r-l+1;i++)p[l+i]=q[i];;
}
int res,l[maxn],r[maxn];
int main()
{
while(~scanf("%d",&n))
{
bit.init();
res=1,tot=0;
for(int i=1,j=0;i<=n;i++)
{
p[i].id=i,p[i].ans=0;
char s[3];int temp;
scanf("%s",s);
if(s[0]=='D')
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].cnt=1;
l[res]=p[i].x,r[res++]=p[i].y;
h[++tot]=p[i].x,h[++tot]=p[i].y;
}
else if(s[0]=='Q')
{
scanf("%d%d",&p[i].x,&p[i].y);
p[i].cnt=0;
h[++tot]=p[i].x,h[++tot]=p[i].y;
}
else
{
scanf("%d",&temp);
p[i].x=l[temp],p[i].y=r[temp];
p[i].cnt=-1;
}
}
sort(h+1,h+tot+1);
tot=unique(h+1,h+tot+1)-h-1;
for(int i=1;i<=n;i++)
{
p[i].x=lower_bound(h+1,h+tot+1,p[i].x)-h;
p[i].y=lower_bound(h+1,h+tot+1,p[i].y)-h;
}
CDQ(1,n);
sort(p+1,p+n+1,cmpid);
for(int i=1;i<=n;i++)
if(!p[i].cnt)printf("%d\n",p[i].ans);
}
return 0;
}