【BZOJ 1176】【Balkan 2007】Mokia
http://www.lydsy.com/JudgeOnline/problem.php?id=1176
分治的例题
把每个询问拆成四个询问,整体二分里x坐标递增,按x坐标扫的时候用树状数组维护y坐标前缀和。
一开始想复杂了,按cdq分治先solve左边再处理中间再solve右边,这样每次都要对x坐标排序,常数巨大,T了好几次TwT
后来参考了别人的代码,发现自己一开始就想复杂了。这道题不需要在solve完后还是保持原来的按x坐标递增的顺序,也不需要先处理出左边的信息才能更新右边的信息。
这样直接分治啊~~~~~处理完一大块左边对右边的贡献再递归处理左右两块。只要一开始对x坐标排序即可,solve的过程从整到散,不需要再进行排序。
一开始还忘了离散化,每次清空树状数组都用memsetヽ(*´Д`*)ノ后来发现从前往后扫一遍把原先加的减回去会快得多。
时间复杂度$O(mlogmlogw)$,m的含义为所有修改和询问的数量,w的含义为离散化y坐标后的y坐标最大值,即树状数组的上界。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&(-x))
using namespace std;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} struct node {
int op, x, y, a, id, pos;
bool operator < (const node &A) const {
return x == A.x ? (y == A.y ? pos < A.pos : y < A.y) : x < A.x;
}
} Q[200003], q[200003]; int s, w, m = 0, ans[40003]; namespace CDQ {
int bits[180003];
void update(int x, int num) {
for(; x <= w; x += lowbit(x)) bits[x] += num;
}
int Qsum(int x) {
int ret = 0;
for(; x; x -= lowbit(x)) ret += bits[x];
return ret;
} void solve(int l, int r) {
if (l == r) return;
int mid = (l + r) >> 1;
for(int i = l; i <= r; ++i) {
if (Q[i].op == 1 && Q[i].id <= mid) update(Q[i].y, Q[i].a);
if (Q[i].op == 2 && Q[i].id > mid) ans[Q[i].pos] += Q[i].a * Qsum(Q[i].y);
} for(int i = l; i <= r; ++i)
if (Q[i].op == 1 && Q[i].id <= mid) update(Q[i].y, -Q[i].a); int tl = l, tr = mid + 1;
for(int i = l; i <= r; ++i)
if (Q[i].id <= mid) q[tl++] = Q[i];
else q[tr++] = Q[i];
for(int i = l; i <= r; ++i) Q[i] = q[i]; solve(l, mid);
solve(mid + 1, r);
}
} int H[180003], cnt = 0, anscnt = 0;
int main() {
s = in(); w = in(); int x1, y1, x2, y2;
for(int x = in(); x != 3; x = in())
if (x == 1) {
Q[++m].op = 1;
Q[m].x = in(); Q[m].y = in(); Q[m].a = in(); Q[m].id = m; Q[m].pos = 0;
H[++cnt] = Q[m].y;
} else {
x1 = in(); y1 = in(); x2 = in(); y2 = in();
H[++cnt] = y1 - 1; H[++cnt] = y2;
ans[++anscnt] = s * (x2 - x1 + 1) * (y2 - y1 + 1);
++m; Q[m] = (node) {2, x1 - 1, y1 - 1, 1, m, anscnt};
++m; Q[m] = (node) {2, x1 - 1, y2, -1, m, anscnt};
++m; Q[m] = (node) {2, x2, y1 - 1, -1, m, anscnt};
++m; Q[m] = (node) {2, x2, y2, 1, m, anscnt};
} sort(H + 1, H + cnt + 1);
cnt = unique(H + 1, H + cnt + 1) - H;
w = cnt - 1; for(int i = 1; i <= m; ++i) Q[i].y = lower_bound(H + 1, H + cnt, Q[i].y) - H; sort(Q + 1, Q + m + 1); CDQ::solve(1, m); for(int i = 1; i <= anscnt; ++i) printf("%d\n", ans[i]); return 0;
}
一定要想好了再码!
【BZOJ 1176】【Balkan 2007】Mokia的更多相关文章
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 【BZOJ】3319: 黑白树
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...
- 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)
http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...
- 【BZOJ】【2084】【POI2010】Antisymmetry
Manacher算法 啊……Manacher修改一下就好啦~蛮水的…… Manacher原本是找首尾相同的子串,即回文串,我们这里是要找对应位置不同的“反回文串”(反对称?233) 长度为奇数的肯定不 ...
- 【BZOJ】1013: [JSOI2008]球形空间产生器sphere
[BZOJ]1013: [JSOI2008]球形空间产生器sphere 题意:给n+1个n维的点的坐标,要你求出一个到这n+1个点距离相等的点的坐标: 思路:高斯消元即第i个点和第i+1个点处理出一个 ...
- 【BZOJ】1002:轮状病毒(基尔霍夫矩阵【附公式推导】或打表)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...
- 【BZOJ】【3083】遥远的国度
树链剖分/dfs序 其实过了[BZOJ][4034][HAOI2015]T2以后就好搞了…… 链修改+子树查询+换根 其实静态树的换根直接树链剖分就可以搞了…… 因为其实只有一样变了:子树 如果roo ...
- 【BZOJ】【2434】【NOI2011】阿狸的打字机
AC自动机+DFS序+BIT 好题啊……orz PoPoQQQ 大爷 一道相似的题目:[BZOJ][3172][TJOI2013]单词 那道题也是在fail树上数有多少个点,只不过这题是在x的fail ...
- 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法
整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...
随机推荐
- 翻译《Writing Idiomatic Python》(五):类、上下文管理器、生成器
原书参考:http://www.jeffknupp.com/blog/2012/10/04/writing-idiomatic-python/ 上一篇:翻译<Writing Idiomatic ...
- NGUI Label Color Code
UILabel的颜色代码 NGUI的Label文档:http://www.tasharen.com/?page_id=166 you can embed colors in [RrGgBb] form ...
- ActiveMQ初体验
首先介绍下MQ,MQ英文名MessageQueue,中文名也就是大家用的消息队列,干嘛用的呢,说白了就是一个消息的接受和转发的容器,可用于消息推送. 下面介绍主题,就是今天为大家介绍的ActiveMQ ...
- java 25 - 4 网络编程之 UDP协议传输思路
UDP传输 两个类:DatagramSocket与DatagramPacket(具体看API) A:建立发送端,接收端. B:建立数据包. C:调用Socket的发送接收方法. D:关闭Socket. ...
- 未找到数据,异常处理:exception when no_data_found then 异常处理语句;
未找到数据. 在 select 字段 Into 变量 from 表 where 条件: 这种语句中很有可能会有select 不到数据的问题,导致报错"未找到数据" 要解决这种问题需 ...
- vpn+路由表,最大限度提高上网速度
Linux使用pptpclient连接VPN后并无自动更改路由,所以需要自己添加一条规则,可以ip这个命令(ppp设备名称可以通过ifconfig查看),执行以下命令即可: root@alexknig ...
- IIS 应用程序池.NET40 重新注册
32位的Windows:---------------------------------------------------------------------------1. 运行->cmd ...
- LINQ 常见用法
以下数据源都假设为data 1.获取某列的不重复数据 List<int> ids = data.Select(t => t.ID).Distinct().ToList(); 2.对 ...
- 通用权限管理系统组件3.9 的 Oracle 数据库创建脚本参考
---------------------------------------------------- -- Export file for user USERCENTER -- -- Create ...
- Linux 网络编程详解七(并发僵尸进程处理)
在上一篇程序框架中,解决了子进程退出,父进程继续存在的功能,但是多条客户端连接如果同一时间并行退出,导致服务器端多个子进程同一时间全部退出,而SIGCHLD是不可靠信号,同时来多条信号可能无法处理,导 ...