【cdq分治】【P4390】[BOI2007]Mokia 摩基亚
Description
给你一个 \(W~\times~W\) 的矩阵,每个点有权值,每次进行单点修改或者求某子矩阵内权值和,允许离线
Input
第一行是两个数字 \(0\) 和矩阵大小 \(W\)
下面每行可能会出现如下参数
\(1,x,y,A\) 单点修改格子 \(x,y\) 为 \(A\)
\(2,x_1,y_1,x_2,y_2\) 查询给定矩阵的权值和
\(3\) 结束查询与修改
Output
对每个查询给出一行作为答案
Hint
\(1~\leq~W~\leq~2000000\)
修改不超过 \(1.6e5\) 个
查询不超过 \(1e4\) 个
保证答案在整形范围内
Solution
这不傻逼题,直接树状数组套treap完事了
我们考虑离线乱搞一下
将查询改为每次查询二维前缀和容斥的形式进行四次单点查询。
我们考虑对 \(x,y\) 的前缀和查询:
我们只需要考虑修改时间在该次查询之前,且 \(x_0~\leq~x~\land~y_0~\leq~y\) 的修改操作 \((x_0,y_0)\)。
我们发现这是一个标准的cdq分治模型:
第一维为时间序,第二维为 \(x\) 坐标,第三维为 \(y\) 坐标。
时间序默认有序,每次考虑前半部分的 \(x_0~\leq~x\) 的点中 \(y_0~\leq~y\) 的点对答案的贡献,用树状数组来统计这部分答案
时间复杂度 \(O(n~\log^2 n)\),空间复杂度 \(O(n~\log n)\)
Code
#include <cstdio>
#include <vector>
#include <iostream>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
int top=0;
do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 2000010;
struct OP {
int x, y, id, v;
inline void print() {
std::cerr << x << ' ' << y << ' ' << id << ' ' << v << std::endl;
}
};
std::vector<OP> Q;
int n, cnt;
int ans[maxn], tree[maxn];
int query(int);
int lowbit(int);
void cdq(int, int);
void update(int, int);
int main() {
freopen("1.in", "r", stdin);
int a, b, c, d;
qr(a); qr(n); a = 0; qr(a);
while (a != 3) {
if (a == 1) {
a = b = c = 0; qr(a); qr(b); qr(c);
Q.push_back({a, b, 0, c});
} else {
a = b = c = d = 0; qr(a); qr(b); qr(c); qr(d);
Q.push_back({c, d, ++cnt, 1});
Q.push_back({a - 1, b - 1, cnt, 1});
Q.push_back({c, b - 1, cnt, -1});
Q.push_back({a - 1, d, cnt, -1});
}
a = 0; qr(a);
}
cdq(0, Q.size() - 1);
for (int i = 1; i <= cnt; ++i) qw(ans[i], '\n', true);
return 0;
}
void cdq(int l, int r) {
if (l == r) return;
int mid = (l + r) >> 1;
cdq(l, mid); cdq(mid + 1, r);
std::vector<OP>temp;
int pre = l;
for (int i = mid + 1; i <= r; ++i) {
while ((pre <= mid) && (Q[pre].x <= Q[i].x)) {
if (Q[pre].id == 0) update(Q[pre].y, Q[pre].v);
temp.push_back(Q[pre++]);
}
ans[Q[i].id] += Q[i].v * query(Q[i].y);
temp.push_back(Q[i]);
}
for (int i = l; i < pre; ++i) if (Q[i].id == 0) update(Q[i].y, -Q[i].v);
while (pre <= mid) temp.push_back(Q[pre++]);
for (int i = l; i <= r; ++i) Q[i] = temp[i - l];
}
inline int lowbit(int x) {return x & -x;}
void update(int x, int v) {
while (x <= n) {
tree[x] += v; x += lowbit(x);
}
}
int query(int x) {
int _ret = 0;
while (x) {
_ret += tree[x];
x -= lowbit(x);
}
return _ret;
}
【cdq分治】【P4390】[BOI2007]Mokia 摩基亚的更多相关文章
- 洛谷 P4390 [BOI2007]Mokia 摩基亚 解题报告
P4390 [BOI2007]Mokia 摩基亚 题目描述 摩尔瓦多的移动电话公司摩基亚(\(Mokia\))设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户 ...
- P4390 [BOI2007]Mokia 摩基亚 (CDQ解决三维偏序问题)
题目描述 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫米.但其真正高科 ...
- Luogu P4390 [BOI2007]Mokia 摩基亚 | CDQ分治
题目链接 $CDQ$分治. 考虑此时在区间$[l,r]$中,要计算$[l,mid]$中的操作对$[mid+1,r]$中的询问的影响. 计算时,排序加上树状数组即可. 然后再递归处理$[l,mid]$和 ...
- [洛谷P4390][BOI2007]Mokia 摩基亚
题目大意: 维护一个W*W的矩阵,每次操作可以增加某格子的权值,或询问某子矩阵的总权值. 题解:CDQ分治,把询问拆成四个小矩形 卡点:无 C++ Code: #include <cstdio& ...
- P4390 [BOI2007]Mokia 摩基亚
传送门 对于一个询问 $(xa,ya),(xb,yb)$,拆成 $4$ 个询问并容斥一下 具体就是把询问变成求小于等于 $xb,yb$ 的点数,减去小于等于 $xa-1,yb$ 和小于等于 $xb,y ...
- P4390 [BOI2007]Mokia 摩基亚(cdq分治)
一样是cdq的板子 照着园丁的烦恼就好了 代码 #include <cstdio> #include <cstring> #include <algorithm> ...
- 【BZOJ1176】[BOI2007]Mokia 摩基亚
[BZOJ1176][BOI2007]Mokia 摩基亚 题面 bzoj 洛谷 题解 显然的\(CDQ\)\(/\)树套树题 然而根本不想写树套树,那就用\(CDQ\)吧... 考虑到点\((x1,y ...
- cogs1752[boi2007]mokia 摩基亚 (cdq分治)
[题目描述] 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能 ...
- [BOI2007]Mokia 摩基亚
Description: 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如"用户C的位置在哪?"的问题,精确到毫 ...
随机推荐
- NuGet 让程序集版本变得混乱
之前引用的 System.Net.Http.Formatting ,是依赖于 System.Net.Http 2.0的. 更新引用后它是依赖于 System.Net.Http 4.0 的.而且一 ...
- No.10_分数分配
C#队一共有7名成员,因此团队贡献分一共350分. 分配方式应当反映绝大部分组员的真实贡献情况,即由贡献决定分数. 另外保证一定的奖惩措施,充分调动组员的积极性,鞭策团队向前迈进. 对于团队贡献分数的 ...
- java实验二实验报告
一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计模式 二.实验过程(本次试验都 ...
- Task 6.2冲刺会议四 /2015-5-17
今天主要是学习并熟悉了C#的开发流程,把他的文件的大体结构和每个组件之间的联系弄清楚之后.开始写服务器部分的内容.学习过程中,感觉网上的资料有些太鱼龙混杂了,不知道该怎么取舍.明天准备完善服务器的功能 ...
- 凡事预则立|项目Beta冲刺准备
1.讨论组长是否重选的议题和结论. 组员一致认为组长不需要重选,我们都很认可组长的表现,组长的付出我们都看在眼里,我们找不出更适合担任组长的人选. 2.下一阶段需要改进完善的功能. 财富值的布局优化以 ...
- java属性编辑器,即PropertyEditor
出处:http://www.iteye.com/topic/1123628
- 转 js事件探秘
Javascript中的事件,可以和html交互. 事件流IE&Opera:事件冒泡其他浏览器: 事件捕获 事件冒泡:事件由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至 ...
- 课堂alpha发布
项目组名:奋斗吧兄弟 今天七组对于各自项目现有的成果进行了alpha发布,下面是我的一些感想. 天天向上团队的连连看游戏: 令我印象最深的是天天向上团队的连连看项目,他们目前能展示给我们的是核心的连连 ...
- Three.js入门篇(一)创建一个场景
上一面讲述了向场景中添加物体对象.这一篇准备把每个功能点细细的讲述一遍,一方面是为了加深自己的理解.另一方面希望能够 帮助到有需要的人. 一.在学习WEBGL的时候,你应该先了解要创建一个WebGL程 ...
- 命令行方式操作O365
这几天公司为O365启用了双因子认证,期间出了些小问题,导致我无法使用管理员账号登入控制台,但是Powershell的方法依旧可以.所以我觉得还是有必要把图形化操作改成脚本操作,以备不时之需.以后凡是 ...