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 ...
随机推荐
- ThreadLocal的坑--ThreadLocal跨线程传递问题
1.父子线程间的传递问题 ThreadLocal的子类InheritableThreadLocal其实已经帮我们处理好了,通过这个组件可以实现父子线程之间的数据传递,在子线程中能够父线程中的Threa ...
- Python 第一式
@Codewars Python练习 question ** Dashatize it ** Given a number, return a string with dash'-'marks bef ...
- golang中switch用法细节
1. switch穿透-fallthrough, 如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透,默认只穿透一层 2. Type Switch: s ...
- php 获取某个月的周一
今天有个朋友问了一个问题,最后解决了下,先整理记下来,后面用到了再说 function getMonday($month = ''){ if(empty($month)){ $month = date ...
- Java并发(思维导图)
1,线程状态转换 无限期等待: 限期等待: 线程生命流程: 2,实现方式 代码实现样例[三种方式]: package com.cnblogs.mufasa.demo2; import java.uti ...
- JavaBean 详细
一.什么是JavaBean? JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方 ...
- java01_简介_开发环境
JAVA的前世今生 美国SUN(Stanford University Network)公司,在中国大陆的正式中文名为"太阳计算机系统(中国)有限公司",在中国台湾的正式中文名为& ...
- SOAP-1概述
简单对象访问协议 SOAP(简单对象访问协议)一般指简单对象访问协议 简单对象访问协议是交换数据的一种协议规范,是一种轻量的.简单的.基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WE ...
- 【原创】大叔经验分享(94)jdbc连接mysql、sqlserver、oracle
Mysql driver下载:https://mvnrepository.com/artifact/mysql/mysql-connector-java import java.sql.*; publ ...
- 记录下js几种常见的数组排序和去重的方法
冒泡排序 , , , , , , , ]; function test(){ ; i < arr.length - ; i++){ ; j < arr.length; j++){ var ...