题目链接

Segments

Time Limit: 4000/2000MS (Java/Others)Memory Limit: 20000/10000KB (Java/Others)

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分治,cdq是陈丹琦orz。。

在我们平常使用的分治中,每一个子问题只解决它本身(可以说是封闭的)。

而在cdq分治中,对于划分出来的两个子问题,前一个子问题用来解决后一个子问题而不是它本身。

具体算法流程如下:

1.将整个操作序列分为两个长度相等的部分(分)

2.递归处理前一部分的子问题(治1)

3.计算前一部分的子问题中的修改操作对后一部分子问题的影响(治2)

4.递归处理后一部分子问题(治3)

另外,能使用常量引用的地方尽量使用,可以提高效率。

Accepted Code:

 /*************************************************************************
> File Name: 1157.cpp
> Author: Stomach_ache
> Mail: sudaweitong@gmail.com
> Created Time: 2014年08月10日 星期日 08时24分10秒
> Propose:
************************************************************************/ #include <cmath>
#include <string>
#include <cstdio>
#include <vector>
#include <fstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = ;
int c[maxn<<], l[maxn], r[maxn], ans[maxn];
struct node {
int t, id, l, r;
node() {}
node(int a, int b, int c, int d) {
t = a; id = b; l = c; r = d;
}
}a[maxn];
vector<int> xs;
int w; bool cmp1(const node &a, const node &b) {
return a.id < b.id;
} bool cmp2(const node &a, const node &b) {
if (a.l != b.l) return a.l < b.l;
return a.r > b.r;
} int lowbit(int x) {
return x & -x;
} void add(int x, int v) {
x = *maxn - x;
while (x < maxn*) {
c[x] += v;
x += lowbit(x);
}
} int sum(int x) {
int res = ;
x = *maxn - x;
while (x > ) {
res += c[x];
x -= lowbit(x);
}
return res;
} void solve(int l, int r) {
if (l >= r) return ;
int mid = (l + r) >> ;
solve(l, mid);
sort(a+l, a+r+, cmp2);
for (int i = l; i <= r; i++) {
if (a[i].id <= mid) {
if (a[i].t == ) add(a[i].r, );
else if (a[i].t == -) add(a[i].r, -);
} else {
if (a[i].t == ) ans[a[i].id] += sum(a[i].r);
}
}
for (int i = l; i <= r; i++) if (a[i].id <= mid) {
if (a[i].t == ) add(a[i].r, -);
if (a[i].t == -) add(a[i].r, );
}
sort(a+l, a+r+, cmp1);
solve(mid+, r);
} int main(void) {
int n;
while (~scanf("%d", &n)) {
int cnt = ;
xs.clear();
for (int i = ; i <= n; i++) {
char s[];
scanf("%s", s);
if (s[] == 'D') {
int x, y;
scanf("%d %d", &x, &y);
xs.push_back(x);
xs.push_back(y);
l[cnt] = x;
r[cnt++] = y;
a[i] = node(, i, x, y);
} else if (s[] == 'Q') {
int x, y;
scanf("%d %d", &x, &y);
xs.push_back(x);
xs.push_back(y);
a[i] = node(, i, x, y);
} else {
int id;
scanf("%d", &id);
a[i] = node(-, i, l[id], r[id]);
}
}
sort(xs.begin(), xs.end());
xs.erase(unique(xs.begin(), xs.end()), xs.end());
w = xs.size();
for (int i = ; i <= n; i++) {
a[i].l = lower_bound(xs.begin(), xs.end(), a[i].l)-xs.begin()+;
a[i].r = lower_bound(xs.begin(), xs.end(), a[i].r)-xs.begin()+;
//printf("%d %d\n", a[i].l, a[i].r);
}
//memset(c, 0, sizeof(c));
memset(ans, , sizeof(ans));
solve(, n);
for (int i = ; i <= n; i++) if (!a[i].t) printf("%d\n", ans[i]);
}
return ;
}

ACdream 1157 (cdq分治)的更多相关文章

  1. acdream 1157Segments cdq分治

    题目链接 #include <iostream> #include <vector> #include <cstdio> #include <cstring& ...

  2. ACdream 1157 Segments(CDQ分治)

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

  3. ACdream 1157 Segments CDQ分治

    题目链接:https://vjudge.net/problem/ACdream-1157 题意: Problem Description 由3钟类型操作: 1)D L R(1 <= L < ...

  4. 【ACdream】1157 Segments cdq分治

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

  5. ACdream 1157 Segments

    Segments Time Limit: 2000ms Memory Limit: 10000KB This problem will be judged on ACdream. Original 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. Python基础(一):程序输入输出、判断合法用户、编写判断成绩的程序

    一.程序输入输出 目标: 编写login.py脚本,实现以下目标: 提示用户输入用户名 将用户名保存在变量中 在屏幕上显示欢迎用户的信息 方案: 编写程序时,很多情况下都需要程序与用户交互.在pyth ...

  2. 75 OpenCV编译、图像处理等

    0 引言 记录图像处理的一些经验和使用OpenCV 等库的注意事项. 1 opencv中的坐标系 一图以蔽之~ 2 opencv 3.4.0 + opencv_contrib + qt编译 主要参考了 ...

  3. 爬虫问题之Unknown command: crawl

    出现这个问题,很大原因是爬虫没有在项目文件夹里运行,因为scrapy 这个爬虫框架封装好的一些命令,必须在框架内环境支持下才能运行 另外在环境目录下,还有很多命令,也必须在此路径环境下才能执行 可以通 ...

  4. MySQL教程和使用手册

    MySQL 教程 MySQL 教程.MySQL 安装.MySQL 管理.MySQL PHP 语法.MySQL 连接.MySQL 创建数据库.MySQL 删除数据库.MySQL 选择数据库.MySQL ...

  5. Centos7防火墙使用

    修改时区 Centos7 #修改时区 timedatectl set-timezone Asia/Shanghai 开启防火墙 #添加一条规则 firewall-cmd --zone=public - ...

  6. Jenkins 搭建篇

    1.Jenkins 介绍 自动化运维工具:saltstack.jenkins.等.因为他们的目标一样,为了我们的软件.构建.测试.发布更加的敏捷.频繁.可靠 如果运维对git不熟,是无法做自动化部署. ...

  7. kruskal算法【最小生成树2】

    设G=(V,E)是无向连通带权图,V={1,2,…,n}: 设最小生成树T=(V,TE),该树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),Kruskal算法将这n个顶点看成是n个孤立的连 ...

  8. Eureka 系列(04)客户端源码分析

    Eureka 系列(04)客户端源码分析 [TOC] 0. Spring Cloud 系列目录 - Eureka 篇 在上一篇 Eureka 系列(01)最简使用姿态 中对 Eureka 的简单用法做 ...

  9. 数据结构与算法简记--redis有序集合实现-跳跃表

    跳表 定义 为一个值有序的链表建立多级索引,比如每2个节点提取一个节点到上一级,我们把抽出来的那一级叫做索引或索引层.如下图所示,其中down表示down指针,指向下一级节点.以此类推,对于节点数为n ...

  10. 聊聊动态链接和dl_runtime_resolve

    写在前面 linux下的动态链接相关结构,重新回顾_dl_runtime_resolve的流程以及利用方法 动态链接相关结构 为了高效率的利用内存,多个进程可以共享代码段.程序模块化方便更新维护等,动 ...