ACdream 1157 Segments(CDQ分治)
来源:互联网 发布:300英雄各级宝石数据 编辑:程序博客网 时间:2024/06/09 03:12
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 222222int 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;}
0 0
- ACdream 1157 Segments(CDQ分治)
- 【ACdream】1157 Segments cdq分治
- ACdream 1157 Segments 【CDQ分治】
- ACdream 1157 Segments(cdq分治)
- ACdream群OJ 1157 cdq分治
- 时间分治(cdq分治)
- bzoj 3262(cdq分治)
- CDQ分治【分治(真得头疼)
- cdq分治
- cdq分治
- cdq分治
- cdq分治
- BNUOJ51279 组队活动(cdq分治&&NTT)
- BZOJ2683 简单题(CDQ分治)
- BZOJ4170 极光(CDQ分治 或 树套树)
- BZOJ 2253 纸箱堆叠(CDQ分治)
- BZOJ 3262 陌上花开(CDQ分治)
- HDU 5324 Boring Class(CDQ分治)
- 为什么构造函数不能是虚函数而析构函数可以
- c++实验3-个人所得税计算器
- 冒泡排序的优化
- 强大的W32Dasm反汇编工具使用教程
- PowerDesigner(一)-PowerDesigner概述(系统分析与建模)
- ACdream 1157 Segments(CDQ分治)
- bzoj 3162: 独钓寒江雪 树形dp&hash
- javascript:类的介绍
- 将一个项目打成一个jar包,导入到另一个项目中并调用
- Java泛型
- SQL Server 2005 cmd工具的使用
- [IOS 开发] automaticallyAdjustsScrollViewInsets属性
- SDUT 3329----顺序表应用5:有序顺序表归并(很经典)
- 界面组件:列表