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 8Sample Output
2
1Hint
注意,删除第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 ...
随机推荐
- vue2 的 过渡(动画)效果
1.在过渡 效果的使用中 ,key属性需要注意 : 有相同父元素的子元素必须有独特的 key.重复的 key 会造成渲染错误. 参考官方说明: https://cn.vuejs.org/ ...
- [NOIP模拟测试37]反思+题解
一定要分析清楚复杂度再打!!!窝再也不要花2h20min用暴力对拍暴力啦!!! 雨露均沾(滑稽),尽量避免孤注一掷.先把暴力分拿全再回来刚正解. 即使剩下的时间不多了也优先考虑认真读题+打暴力而非乱搞 ...
- Dart 和 Flutter 使用json_annotation和json_serializable来处理json数据教程
在学习fultter的时候突然想到如何去处理从服务器获取的json或者将app中的对象数据转换成json上传给服务器 于是研究一下dart对json数据的处理 首先需要依赖下面的第三方库(这里要强调下 ...
- MySQL 小数处理函数 round 和 floor
一. 在mysql中,round函数用于数据的四舍五入,它有两种形式: 1.round(x,d) ,x指要处理的数,d是指保留几位小数 这里有个值得注意的地方是,d可以是负数,这时是指定小数点左边的 ...
- 2017《Java技术》预备作业 计科1502任秀兴
阅读邹欣老师的博客,谈谈你期望的师生关系是什么样的? 我认为,学生和老师的关系,应该亦师亦友.可以以一种朋友的身份去进行教学,是我们理想中的课堂. 在生活中,老师和我们应该多沟通,成为朋友,在有感情的 ...
- Linux中的特殊权限s、t、i、a
文件权限除了r.w.x外还有s.t.i.a权限:s:文件属主和组设置SUID和GUID,文件在被设置了s权限后将以root身份执行.在设置s权限时文件属主.属组必须先设置相应的x权限,否则s权限并不能 ...
- Leetcode代码复盘_动态规划
动态规划中包含3个重要的概念: 1.最优子结构 2.边界 3.状态转移公式 以跳台阶为例,最优子结构为f(10)=f(9) + f(8),边界是f(1)=1, f(2)=2,状态转移公式f(n)=f( ...
- 8.Jmeter 快速入门教程 -- 如何使测试脚本更强大
添加基本的elements例如Sampler 或者一些监听器,就可以完成基本的测试.但有时需要更复杂的测试场景,所以还有更多其他的元素.清看下表,了解各种单元组的用途. 可添加的单元组 用途 Sa ...
- Win7下VS2008安装cocos2d-2.0-x-2.0.4模板时, 运行InstallWizardForVS2008.js文件执行失败的解决办法
今天在Win7环境下的VS2008中安装cocos2d-x模板的过程中,当点击InstallWizardForVS2008.js时,弹出" 没有文件扩展'.js'的脚本引擎&q ...
- Spingboot整合Redis,用注解(@Cacheable、@CacheEvict、@CachePut、@Caching)管理缓存
背景:项目从头开始,需结合Springboot和Redis 需求:用注解管理缓存 方法: 一.用Redis取代Springboot原有缓存 1.pom引入依赖 2.applicatio ...