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 ...
随机推荐
- Thinking In Java 4th Chap6 访问权限控制
引入一个包及其所包含的方法:import java.util.ArrayList;(引入java.util包,并引入了包中的ArrayList类) import java.util.*;(引入了jav ...
- ORACLE 的前后台进程
关于oracle用户进程,服务进程,后台进程 用户进程(User Process) 是一个需要与Oracle Server交互的程序 运行于客户端 当用户运行某个工具或应用程序(如SQL*Plus)时 ...
- JPA扩展(自定义sql)
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- JS 08表单操作_表单域
一.表单的获取方式 document.getElementById() document.forms[index]; document.forms[form_name] document.form_n ...
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
- python __enter__ 与 __exit__的作用,以及与 with 语句的关系(转)
https://blog.csdn.net/xc_zhou/article/details/80810111 python __enter__ 与 __exit__的作用,以及与 with 语句的关系
- Unity性能优化-DrawCall
1. DrawCall是啥?其实就是对底层图形程序(比如:OpenGL ES)接口的调用,以在屏幕上画出东西.所以,是谁去调用这些接口呢?CPU.比如有上千个物体,每一个的渲染都需要去调用一次底层接口 ...
- C#使用Selenium网页自动化
工作中很多时候经常需要网抓数据或者把数据填写到网站上,使用Selenium将其自动化是一种不错的选择.Selenium其实是一个用于Web应用程序测试的工具,测试你的应用程序看是否能够很好地工作在不同 ...
- h5获取地理坐标
h5获取地理坐标 方法:h5自带获取地理信息的api api:navigator.geolocation.getCurrentPosition https://developer.mozilla.or ...
- 使用nodejs连接mysql数据库实现增删改查
首先要有数据库 使用xampp 或者 phpstudy 可以傻瓜式安装 新建一个项目文件夹 之后在这个目录下初始化package.json (npm init) 先在项目中安装mysql 和 ex ...