BZOJ4170 极光(CDQ分治 或 树套树)
传送门
BZOJ上的题目没有题面……
【样例输入】
3 5
2 4 3
Query 2 2
Modify 1 3
Query 2 2
Modify 1 2
Query 1 1
【样例输出】
2
3
3
这道题稍微分析一下就知道是求一个一个点曼哈顿距离小于k的的范围内的点的个数(把下标看做x,把值看做y)。然后我们只需要旋转一下坐标轴就变成了和“Mokia”或“简单题”一样的CDQ分治裸题了,求二维空间前缀和。
首先将询问按x排序,然后开始分治过程,计算左半区间对右半区间的贡献,然后就写完了呀!
然后是树套树做法,这个就更Naive了呀,直接套,反正就是求区间前缀和,乱搞搞就A了(不知道为什么对内存的需求不对啊……)。
CDQ版:
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <assert.h>
#define LL int
#define MAXM 300005
#define MAXN 100005
using namespace std;
int a[MAXN];
LL ans[MAXN];
inline int Min(int a, int b) { return a < b ? a : b; }
struct Querys{
int t, x, y, v, k; Querys(){}
Querys(int a, int b, int c, int d, int e):t(a),x(b),y(c),v(d),k(e){}
inline bool operator < (const Querys &r) const {
if(x == r.x && y == r.y) return t < r.t;
else if(x == r.x) return y < r.y;
else return x < r.x;
}
} q[MAXM], nq[MAXM];
int n, m, cnt = 0, qn, N;
inline void GET(int &n) {
char c; n = 0;
do c=getchar(); while('0' > c || c > '9');
do n=n*10+c-'0',c=getchar(); while('0' <= c && c <= '9');
}
namespace BIT {
LL t[MAXM];
inline void Add(int x, int v) {
for(; x <= N; x += x&-x) t[x] += v;
}
inline LL Q(int x, LL sum = 0) {
for(; x; x -= x&-x) sum += t[x];
return sum;
}
}
void cdq(int L, int R) {
if(L >= R) return;
using namespace BIT;
int mid = (L + R) >> 1, lp = L, rp = mid+1;
for(int i = L; i <= R; ++ i)
if(q[i].t <= mid && q[i].k == 2) Add(q[i].y, 1);
else if(q[i].t > mid && q[i].k != 2) ans[q[i].v] += Q(q[i].y) * q[i].k;
for(int i = L; i <= R; ++ i) {
if(q[i].t <= mid && q[i].k == 2) Add(q[i].y, -1);
if(q[i].t <= mid) nq[lp ++] = q[i];
else nq[rp ++] = q[i];
}
for(int i = L; i <= R; ++ i) q[i] = nq[i];
cdq(L, mid); cdq(mid+1, R);
}
int main() {
GET(n); GET(m); N = 300000;
for(int i = 1; i <= n; ++ i) {
GET(a[i]);
q[++ cnt] = Querys(cnt, i + a[i], a[i] - i + 160000, 0, 2);
}
char op[10]; int u, v;
for(int i = 1; i <= m; ++ i) {
scanf("%s", op);
GET(u); GET(v);
if('M' == op[0]) {
a[u] = v;
q[++ cnt] = Querys(cnt, u + v, v - u + 160000, 0, 2);
}
else {
++ qn; assert(a[u]-u-v+160000-1 > 0);
if(u+a[u]-v-1 > 0) q[++ cnt] = Querys(cnt, (u+a[u]-v-1), Min(a[u]-u+v+160000, N), qn, -1);
if(u+a[u]-v-1 > 0) q[++ cnt] = Querys(cnt, (u+a[u]-v-1), Min(a[u]-u-v+160000-1,N), qn, 1);
q[++ cnt] = Querys(cnt, (u+a[u]+v), Min(a[u]-u+v+160000,N), qn, 1);
q[++ cnt] = Querys(cnt, (u+a[u]+v), Min(a[u]-u-v+160000-1,N), qn, -1);
}
}
sort(q+1, q+cnt+1);
cdq(1, cnt);
for(int i = 1; i <= qn; ++ i)
printf("%d\n", ans[i]);
return 0;
}
树套树版:
#include <cstdio>
#define MAXN 1000005
inline void GET(int &n) {
char c, f = 1; n = 0;
do if((c=getchar()) == '-') f = -1; while('0' > c || c > '9');
do n=n*10+c-'0',c=getchar(); while('0' <= c && c <= '9');
n *= f;
}
unsigned fix[MAXN * 20], sd = 2333;
int key[MAXN * 20], s[MAXN * 20][2], sz[MAXN * 20], rt[MAXN], cnt, n, m, N, a[MAXN], num[MAXN];
inline unsigned ran() { return sd = sd * sd + sd^27873; }
inline void pushup(int x) {
sz[x] = sz[s[x][0]] + sz[s[x][1]] + num[x];
}
inline void rot(int &x, bool f) {
int t = s[x][f]; s[x][f] = s[t][f^1]; s[t][f^1] = x;
pushup(x); pushup(t); x = t;
}
void Insert(int &x, int v) {
if(!x) { x = ++ cnt; fix[x] = ran(); num[x] = sz[x] = 1; key[x] = v; return; }
if(v == key[x]) { ++ num[x]; pushup(x); return; }
bool f = key[x] < v;
Insert(s[x][f], v); pushup(x);
if(fix[s[x][f]] > fix[x]) rot(x, f);
} int u, v, i;
int Rank(int x, int v) {
if(!x) return 0;
if(key[x] < v) return sz[x] - sz[s[x][1]] + Rank(s[x][1], v);
else if(key[x] > v) return Rank(s[x][0], v);
else return sz[x] - sz[s[x][1]];
}
void Ins(int x, int v) {
for(; x <= N; x += x&-x)
Insert(rt[x], v);
}
int Q(int x, int y) {
int sum = 0;
for(; x > 0; x -= x&-x)
sum += Rank(rt[x], y);
return sum;
}
int main() {
GET(n); GET(m); N = 2*n + 100000;
for(int i = 1; i <= n; ++ i) {
GET(a[i]); Ins(i+a[i], a[i]-i);
}
char op[10];
for(i = 1; i <= m; ++ i) {
scanf("%s", op);
GET(u); GET(v);
if('M' == op[0]) {
a[u] = v; Ins(u+a[u], a[u]-u);
}
else {
int ans = Q((u+a[u]+v), a[u]-u+v) - Q((u+a[u]-v-1), a[u]-u+v) - Q((u+a[u]+v), a[u]-u-v-1) + Q((u+a[u]-v-1), a[u]-u-v-1);
printf("%d\n", ans);
}
}
return 0;
}
BZOJ4170 极光(CDQ分治 或 树套树)的更多相关文章
- BZOJ4170:极光(CDQ分治)
Description "若是万一琪露诺(俗称rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她 ...
- 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)
[题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...
- bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
模板题,折腾了许久. cqd分治整体二分,感觉像是把询问分到答案上. #include <bits/stdc++.h> #define rep(i, a, b) for (int i = ...
- bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)
Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...
- [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...
- Codechef-ANCESTOR(树套树/CDQ分治)
题意: 给定两棵有根树,各有 N 个点.两棵树上的点分别被从 1 到 N 标号.两棵树的根均为标号为 1 的节点. 你的任务非常简单:对于每个 i,找到一个 j(j != i),使得在两棵树中 j 都 ...
- BZOJ 3262 cdq分治 OR 树套树
注意判断 三个条件都一样的-- (CDQ分治 其实并不是很难理解 只是想不到--) CDQ分治: //By SiriusRen #include <cstdio> #include < ...
- 2019南昌网络赛-I. Yukino With Subinterval 线段树套树状数组,CDQ分治
TMD...这题卡内存卡的真优秀... 所以以后还是别用主席树的写法...不然怎么死的都不知道... 树套树中,主席树方法开权值线段树...会造成空间的浪费...这道题内存卡的很紧... 由于树套树已 ...
- [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)
题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...
随机推荐
- Webstorm官方最新版本for Mac版本 不用注册码/破坏原文件
首先,说明下我自己安装的时候看到网上无外乎两种方法: 下载别人封装好的安装包,把JetbrainsCrack.jar复制到/Applications/WebStorm.app/Contents/bin ...
- hdu 1872(看病要排队)(优先队列)
看病要排队 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- asp.net 将word文档进行编辑并导出一个新的word
最近做项目,需要多word文档进行编辑并导出一个新的word,在最初的word编辑中留下特定的字符串用来替换,然后在本地生成一个新的word文档,并且不修改服务器中的word文档,这样才能保证服务器中 ...
- java 中 Math.rint()
Math.rint() **形参是 double System.out.println(Math.rint(2.5)); 返回 2.0 System.out.println(Math.rint(2.5 ...
- Kinect2在线重建(Tracking and Mapping)
前言 个人理解错误的地方还请不吝赐教,转载请标明出处,内容如有改动更新,请看原博:http://www.cnblogs.com/hitcm/ 如有任何问题,feel free to ...
- js从服务器下载文件
通常,将文件绝对路径url作为超链接<a>的链接地址href的值,点击<a>后,浏览器将会尝试请求文件资源,如果浏览器能够辨认文件类型,则将会以预设的打开方式直接打开下载的文件 ...
- django+nginx+xshell简易日志查询,接上<关于《rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>》的反思>
纠正一下之前在<关于<rsyslog+mysql+loganalyzer搭建日志服务器<个人笔记>>的反思>中说到的PHP+MySQL太慢,这里只是说我技术不好,没 ...
- [修改后]html+css 做成一个可浏览的表格
现在表格内容需要显示的要求如下: 1, 表格很大,界面放不小,需要放到div中. 2, 在div中可以用scroll滑动查看. 3, td中的内容保持在一行中. 4, 可以点击tr,然后可以选中并了解 ...
- js动态生成二维码图片
1.html代码 <div id="qrcode" style="width:200px; height:200px;position: fixed;bottom: ...
- hbuilder中如何使用egit上传项目
刚开始使用时,我也是遵照网上的教程来的,其实就那一篇教程,到处被转载,怎么搜都是那一个,实际操作发现有点小不同,所以实际截图给大家一个参考. 1.首先肯定是进入hbuilder下载egit插件啦.(工 ...