SEERC 2018 B. Broken Watch (CDQ分治)
题目链接:http://codeforces.com/gym/101964/problem/B
题意:q 种操作,①在(x,y)处加一个点,②加一个矩阵{(x1,y1),(x2,y2)},问每次操作后点在矩阵中或矩阵边界上的对数有多少。
题解:裸的CDQ分治,考虑对点和矩阵分别进行CDQ分治,因为x,y <= 1e9,要将其中一个坐标离散化。要注意先加点和先加矩阵的两种情况下,矩阵的差分边界是不同的。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int MAXN = 1e5 + ;
const int MAXM = 1e8 + ;
const ll mod = 1e9 + ; struct node {
int op, x1, y1, x2, y2, id;
bool operator < (const node &rhs) {
if(x1 != rhs.x1)
return x1 < rhs.x1;
return id < rhs.id;
}
} a[MAXN], b[MAXN << ], c[MAXN << ]; int tot; void addnode(int op, int x1, int y1, int id) {
++tot;
b[tot].op = op, b[tot].x1 = x1, b[tot].y1 = y1, b[tot].id = id;
} int y[MAXN << ], ysz = ;
ll ans[MAXN]; int lowbit(int x) {
return x & (-x);
} ll bit[MAXN << ]; void add(int y, int val) {
while(y <= ysz) {
bit[y] += val;
y += lowbit(y);
}
} ll query(int y) {
ll sum = ;
while(y) {
sum += bit[y];
y -= lowbit(y);
}
return sum;
} void cdq(int l, int r) {
if(l == r)
return ;
int mid = (l + r) >> ;
cdq(l, mid);
cdq(mid + , r);
int len = ;
for(int i = l; i <= mid; i++)
if(b[i].id == )
c[++len] = b[i];
for(int i = mid + ; i <= r; i++)
if(b[i].id)
c[++len] = b[i];
if(len == || c[].id || c[len].id == )
return ;
sort(c + , c + + len);
for(int i = ; i <= len; i++) {
if(c[i].id == )
add(c[i].y1, c[i].op);
else
ans[c[i].id] += 1ll * c[i].op * query(c[i].y1);
}
for(int i = ; i <= len; i++)
if(c[i].id == )
add(c[i].y1, -c[i].op);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
mst(ans, );
int q;
scanf("%d", &q);
for(int i = ; i <= q; i++) {
scanf("%d%d%d", &a[i].op, &a[i].x1, &a[i].y1);
y[++ysz] = a[i].y1;
if(a[i].op == ) {
scanf("%d%d", &a[i].x2, &a[i].y2);
y[++ysz] = a[i].y2;
}
}
sort(y + , y + + ysz);
ysz = unique(y + , y + + ysz) - y - ;
for(int i = ; i <= q; i++) {
a[i].y1 = lower_bound(y + , y + + ysz, a[i].y1) - y;
if(a[i].op == )
a[i].y2 = lower_bound(y + , y + + ysz, a[i].y2) - y;
}
tot = ;
for(int i = ; i <= q; i++) {
if(a[i].op == ) {
addnode(, a[i].x1, a[i].y1, );
} else {
addnode(, a[i].x1 - , a[i].y1 - , i);
addnode(-, a[i].x2, a[i].y1 - , i);
addnode(-, a[i].x1 - , a[i].y2, i);
addnode(, a[i].x2, a[i].y2, i);
}
}
cdq(, tot);
tot = ;
for(int i = ; i <= q; i++) {
if(a[i].op == ) {
addnode(, a[i].x1, a[i].y1, i);
} else {
addnode(, a[i].x1, a[i].y1, );
addnode(-, a[i].x2 + , a[i].y1, );
addnode(-, a[i].x1, a[i].y2 + , );
addnode(, a[i].x2 + , a[i].y2 + , );
}
}
cdq(, tot);
for(int i = ; i <= q; i++) {
ans[i] += ans[i - ];
printf("%lld\n", ans[i]);
}
return ;
}
SEERC 2018 B. Broken Watch (CDQ分治)的更多相关文章
- 2018.10.01 bzoj3237: [Ahoi2013]连通图(cdq分治+并查集)
传送门 cdq分治好题. 对于一条边,如果加上它刚好连通的话,那么删掉它会有两个大集合A,B.于是我们先将B中禁用的边连上,把A中禁用的边禁用,再递归处理A:然后把A中禁用的边连上,把B中禁用的边禁用 ...
- 2018.06.30 cdq分治
#cdq分治 ##一种奇妙的分治方法 优点:可以顶替复杂的高级数据结构:常数比较小. 缺点:必须离线操作. CDQ分治的基本思想十分简单.如下: 我们要解决一系列问题,包含修改和查询操作,我们将这些问 ...
- 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018)
layout: post title: 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 201 ...
- 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution
A. Numbers Unsolved. B. Broken Watch Solved. 题意: 一个圆盘上,有等分的n块区域,有三根指针,当三根指针分别位于两块区域的交界处时 指针的三点相连会形成一 ...
- [CQOI2011]动态逆序对 CDQ分治
洛谷上有2道相同的题目(基本是完全相同的,输入输出格式略有不同) ---题面--- ---题面--- CDQ分治 首先由于删除是很不好处理的,所以我们把删除改为插入,然后输出的时候倒着输出即可 首先这 ...
- 【教程】简易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 ...
随机推荐
- Win10 改为用 Ctrl+Shift 切换中英输入语言而不是 Win+空格
是切换中英输入语言,而不是切换输入法,如图: 步骤: 设置 > 设备 > 输入 > 高级键盘设置 > 语言栏选项 > 高级键盘设置 > 更改按键顺序 > 切换 ...
- Python之正则表达式笔记
概述 概念 Regular Expression 一种文本模式,描述在搜索文本时要匹配的一个或多个字符串 典型场景 数据验证.文本扫描.文本提取.文本替换.文本分割 语法 字面值 普通字符 需转义:\ ...
- Python面试题集合带答案
目录 Python基础篇 1:为什么学习Python 2:通过什么途径学习Python 3:谈谈对Python和其他语言的区别 Python的优势: 4:简述解释型和编译型编程语言 5:Python的 ...
- Luogu4770 NOI2018你的名字(后缀自动机+线段树合并)
先考虑l=1,r=n,并且不要求本质不同的情况.对原串建SAM,将询问串在上面跑,得到每个前缀的最长匹配后缀即可得到答案. 然后考虑本质不同.对询问串也建SAM,统计每个节点的贡献,得到该点right ...
- This is very likely to create a memory leak. Stack trace of thread错误分析
1.问题描述 启动tomcat部署项目时,报This is very likely to create a memory leak. Stack trace of thread错误. 29-May-2 ...
- 怎样获取当前对象的原型对象prototype
1. 使用 Object.getPrototypeOf(); function Person(name){ this.name = name; } var lilei = new Person(&qu ...
- map自定义键值类型
map自定义键值类型 改变Map的默认比较方式 https://www.cnblogs.com/zjfdlut/archive/2011/08/12/2135698.html 大家知道,STL中的ma ...
- java封装数据类型——Boolean
众所周知,java对常见的原始数据类型都提供了对应的封装类型,增加一些常用的特性(如 计算hash值.比较相等.类型转换等),以扩展他们对数据处理的能力,使得他们更好地适应面向对象编程的各种场景.今天 ...
- Eclipse 设置代码模板
checkstyle插件 安装 从 http://sourceforge.jp/projects/sfnet_eclipse-cs/releases/ 下载 net.sf.eclipsecs-upda ...
- C++ 函数重载二义性
说起函数重载,我不由得想起了C++的“多态”特性.多态又分为静态(编译时)多态和动态(运行时)多态,静态多态即为函数重载,动态多态则是虚函数机制.虚函数水较深,先不讨论,今天我们来看一下函数重载.作用 ...