题目链接:https://vjudge.net/problem/ACdream-1157

题意:

Problem 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)
给出N,接下来N行,每行是3种类型之一

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

Hint

注意,删除第i条增加的线段,不是说第i行,而是说第i次增加。

比如

D 1 10

Q 1 10

D 2 3

D 3 4

Q 5 6

D 5 6

C 2是删除D 2 3

C 4是删除D 5 6

解法: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]中即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
int n, h[maxn], tot;
struct node{
int x,y,cnt,id,ans;
bool operator<(const node &rhs) const{
if(y!=rhs.y)return y>rhs.y;
return x<rhs.x;
}
}p[maxn],q[maxn];
bool cmp(node a, node b){
return a.id<b.id;
}
struct BIT{
int b[maxn];
void init(){
memset(b, 0, sizeof(b));
}
inline int lowbit(int x){
return (x&(-x));
}
void add(int x, int v){
while(x<=tot){
b[x]+=v;
x+=lowbit(x);
}
}
int query(int x){
int ret = 0;
while(x){
ret += b[x];
x -= lowbit(x);
}
return ret;
}
}bit;
void CDQ(int l, int r){
if(l == r) return;
int mid = (l+r)/2;
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.add(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.add(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();
tot=0,res=1;
for(int i=1; i<=n; i++){
p[i].id = i, p[i].ans = 0;
char op[3];
scanf("%s", op);
if(op[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(op[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{
int temp;
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,cmp);
for(int i=1; i<=n; i++){
if(!p[i].cnt) printf("%d\n", p[i].ans);
}
}
return 0;
}

ACdream 1157 Segments CDQ分治的更多相关文章

  1. 【ACdream】1157 Segments cdq分治

    Segments   Problem Description 由3钟类型操作:1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]2)C i ...

  2. ACdream 1157 (cdq分治)

    题目链接 Segments Time Limit: 4000/2000MS (Java/Others)Memory Limit: 20000/10000KB (Java/Others) Problem ...

  3. ACdream 1157 Segments(CDQ分治)

    题目链接:http://acdream.info/problem?pid=1157 Problem Description 由3钟类型操作:1)D L R(1 <= L <= R < ...

  4. ACdream 1157 Segments

    Segments Time Limit: 2000ms Memory Limit: 10000KB This problem will be judged on ACdream. Original I ...

  5. ACdream1157 Segments(CDQ分治 + 线段树)

    题目这么说的: 进行如下3种类型操作:1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]2)C i (1-base) 删除第i条增加的线段, ...

  6. 【教程】简易CDQ分治教程&学习笔记

    前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦!       CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...

  7. BZOJ 2683 简单题 ——CDQ分治

    [题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...

  8. HDU5618 & CDQ分治

    Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...

  9. 初识CDQ分治

    [BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 200 ...

随机推荐

  1. 【bzoj1712】[Usaco2007 China]Summing Sums 加密 矩阵乘法

    题目描述 那N只可爱的奶牛刚刚学习了有关密码的许多算法,终于,她们创造出了属于奶牛的加密方法.由于她们并不是经验十足,她们的加密方法非常简单:第i只奶牛掌握着密码的第i个数字,起始的时候是Ci(0≤C ...

  2. [NOIP2010] 引水入城 贪心 + 记忆化搜索

    ---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...

  3. [APIO2017]商旅 0/1分数规划

    ---题面--- 题解: upd: 在洛谷上被Hack了...思路应该是对的,代码就别看了 感觉有个地方还是非常妙的,就是因为在x买东西,在y卖出,就相当于直接从x走向了y,因为经过中间的城市反正也不 ...

  4. Javascript中的date对象和getTime()方法

    有些时候我们需要计算两个日期间的天数,或者小时数等等.下面用JavaScript实现这个需求,然后学习一下需要用到的一些JavaScript函数. JavaScript程序如下: 1 <scri ...

  5. Python通过PhantomJS获取JS渲染后的网页源代码

    新建一个文件,命名为test.js,内容如下: var page = require('webpage').create(), system = require('system'), address; ...

  6. RobHess的SIFT源码分析:imgfeatures.h和imgfeatures.c文件

    SIFT源码分析系列文章的索引在这里:RobHess的SIFT源码分析:综述 imgfeatures.h中有SIFT特征点结构struct feature的定义,除此之外还有一些特征点的导入导出以及特 ...

  7. Codeforces Round #402 (Div. 2) A B C sort D二分 (水)

    A. Pupils Redistribution time limit per test 1 second memory limit per test 256 megabytes input stan ...

  8. liunx系统下安装mysql数据库5.7.13版本

    一:在/usr/local目录下解压安装包

  9. 在windows下如何使用密钥对远程登录服务器?

    在企业的生产中相信各位朋友都会使用远程登录服务器,这样即高效也非常方便,(服务器在西藏,没有远程技术,公司在北京,你只能到西藏与机器相伴,在这里我使用xshell软件),我们使用ssh 服务登录服务器 ...

  10. 确保web安全的https、确认访问用户身份的认证(第七章、第八章)

    第七章 确保web安全的https 1.http的缺点: (1)通信使用明文,内容可能会被窃听 (2)不验证通信方的身份,因此有可能遭遇伪装 (3)无法证明报文的完整性,因此有可能已遭篡改. 2.通信 ...