ACdream 1157 (cdq分治)
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分治)的更多相关文章
- acdream 1157Segments cdq分治
题目链接 #include <iostream> #include <vector> #include <cstdio> #include <cstring& ...
- ACdream 1157 Segments(CDQ分治)
题目链接:http://acdream.info/problem?pid=1157 Problem Description 由3钟类型操作:1)D L R(1 <= L <= R < ...
- ACdream 1157 Segments CDQ分治
题目链接:https://vjudge.net/problem/ACdream-1157 题意: Problem Description 由3钟类型操作: 1)D L R(1 <= L < ...
- 【ACdream】1157 Segments cdq分治
Segments Problem Description 由3钟类型操作:1)D L R(1 <= L <= R <= 1000000000) 增加一条线段[L,R]2)C i ...
- ACdream 1157 Segments
Segments Time Limit: 2000ms Memory Limit: 10000KB This problem will be judged on ACdream. Original I ...
- 【教程】简易CDQ分治教程&学习笔记
前言 辣鸡蒟蒻__stdcall终于会CDQ分治啦! CDQ分治是我们处理各类问题的重要武器.它的优势在于可以顶替复杂的高级数据结构,而且常数比较小:缺点在于必须离线操作. CDQ分治的基 ...
- BZOJ 2683 简单题 ——CDQ分治
[题目分析] 感觉CDQ分治和整体二分有着很本质的区别. 为什么还有许多人把他们放在一起,也许是因为代码很像吧. CDQ分治最重要的是加入了时间对答案的影响,x,y,t三个条件. 排序解决了x ,分治 ...
- HDU5618 & CDQ分治
Description: 三维数点 Solution: 第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了... Code: /*=============================== ...
- 初识CDQ分治
[BZOJ 1176:单点修改,查询子矩阵和]: 1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 200 ...
随机推荐
- Service系统服务(一):安装一个KVM服务器、KVM平台构建及简单管理、virsh基本管理操作、xml配置文件的应用、为虚拟机制作快照备份、快建新虚拟机
一.安装一个KVM服务器 目标: 本例要求准备一台 RHEL7.2 服务器,将其搭建为KVM平台,主要完成下列操作: 1> 关闭本机的SELinux保护.防火墙服务 2> 挂载RHEL ...
- Python基础教程(007)--Python的优缺点
前言 了解Python的优点和缺点 知识点 优点 简单易学 免费,开源 面相对象 丰富的库 可扩展性 缺点 运行速度慢 国内市场较小 中文资料匮乏 总结: 明白Python的优点和缺点
- MFC不同窗口之间传递数据
问题的由来: 最近在学习串口通信编程,参考的例子大多数都是在一个对话框中同时完成对串口的配置及数据收发的功能.这种方式不太适合于写自己的应用程序(会使得程序界面比较混乱,无法突出程序的重点),因此想让 ...
- NOIWC2019 懵逼记
弱省蒟蒻,第一次也是最后一次来冬令营.. Day [-inf,-1] \(woc\)咋啥都听不懂,没错在下划水王. Day 0 白天上课继续划水..晚上跑去试机,骗了半天交互的分就滚了..半夜里竟然睡 ...
- tomcat的stratup小黑框名字修改
Tomcat的bin目录下:catalina.out文件, TITLE就是Tomcat startup窗口的名称,282行默认是:Tomcat.这里建议改成“服务名+端口号”的方式,看起来一目了然.因 ...
- 团队冲刺DAY4
DES算法 算法概要 在DES.java当中创立两个方法分别用作加密和解密 通过 `public static byte[] encrypt(byte[] data, String sKey) 创建方 ...
- centos7 rm -rf 删除文件的找回
今天手贱一不小心把我正个项目目录删除了,没办法只能找回啦 文件系统是ext4的,只能使用extundelete df -hT 文件名 查看 下删除的文件夹所在的硬盘 1. 安装依赖 ...
- 83、Tensorflow中的变量管理
''' Created on Apr 21, 2017 @author: P0079482 ''' #如何通过tf.variable_scope函数来控制tf.ger_variable函数获取已经创建 ...
- thymeleaf数组下标
<tr th:if="${exercisers != null}"th:each="exerciser:${exercisers}"> <td ...
- vue事件修饰符(once:prev:stop)
vue事件修饰符(once:prev:stop) stop修饰符 效果如下: 当你鼠标在这个div里的时候,x与y的值:会随着鼠标的变化而变化.但是当鼠标放在stopMoving的时候,x与y的值是 ...