传送门

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版:

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <assert.h>
  5. #define LL int
  6. #define MAXM 300005
  7. #define MAXN 100005
  8. using namespace std;
  9. int a[MAXN];
  10. LL ans[MAXN];
  11. inline int Min(int a, int b) { return a < b ? a : b; }
  12. struct Querys{
  13. int t, x, y, v, k; Querys(){}
  14. Querys(int a, int b, int c, int d, int e):t(a),x(b),y(c),v(d),k(e){}
  15. inline bool operator < (const Querys &r) const {
  16. if(x == r.x && y == r.y) return t < r.t;
  17. else if(x == r.x) return y < r.y;
  18. else return x < r.x;
  19. }
  20. } q[MAXM], nq[MAXM];
  21. int n, m, cnt = 0, qn, N;
  22. inline void GET(int &n) {
  23. char c; n = 0;
  24. do c=getchar(); while('0' > c || c > '9');
  25. do n=n*10+c-'0',c=getchar(); while('0' <= c && c <= '9');
  26. }
  27. namespace BIT {
  28. LL t[MAXM];
  29. inline void Add(int x, int v) {
  30. for(; x <= N; x += x&-x) t[x] += v;
  31. }
  32. inline LL Q(int x, LL sum = 0) {
  33. for(; x; x -= x&-x) sum += t[x];
  34. return sum;
  35. }
  36. }
  37. void cdq(int L, int R) {
  38. if(L >= R) return;
  39. using namespace BIT;
  40. int mid = (L + R) >> 1, lp = L, rp = mid+1;
  41. for(int i = L; i <= R; ++ i)
  42. if(q[i].t <= mid && q[i].k == 2) Add(q[i].y, 1);
  43. else if(q[i].t > mid && q[i].k != 2) ans[q[i].v] += Q(q[i].y) * q[i].k;
  44. for(int i = L; i <= R; ++ i) {
  45. if(q[i].t <= mid && q[i].k == 2) Add(q[i].y, -1);
  46. if(q[i].t <= mid) nq[lp ++] = q[i];
  47. else nq[rp ++] = q[i];
  48. }
  49. for(int i = L; i <= R; ++ i) q[i] = nq[i];
  50. cdq(L, mid); cdq(mid+1, R);
  51. }
  52. int main() {
  53. GET(n); GET(m); N = 300000;
  54. for(int i = 1; i <= n; ++ i) {
  55. GET(a[i]);
  56. q[++ cnt] = Querys(cnt, i + a[i], a[i] - i + 160000, 0, 2);
  57. }
  58. char op[10]; int u, v;
  59. for(int i = 1; i <= m; ++ i) {
  60. scanf("%s", op);
  61. GET(u); GET(v);
  62. if('M' == op[0]) {
  63. a[u] = v;
  64. q[++ cnt] = Querys(cnt, u + v, v - u + 160000, 0, 2);
  65. }
  66. else {
  67. ++ qn; assert(a[u]-u-v+160000-1 > 0);
  68. 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);
  69. 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);
  70. q[++ cnt] = Querys(cnt, (u+a[u]+v), Min(a[u]-u+v+160000,N), qn, 1);
  71. q[++ cnt] = Querys(cnt, (u+a[u]+v), Min(a[u]-u-v+160000-1,N), qn, -1);
  72. }
  73. }
  74. sort(q+1, q+cnt+1);
  75. cdq(1, cnt);
  76. for(int i = 1; i <= qn; ++ i)
  77. printf("%d\n", ans[i]);
  78. return 0;
  79. }

树套树版:

  1. #include <cstdio>
  2. #define MAXN 1000005
  3. inline void GET(int &n) {
  4. char c, f = 1; n = 0;
  5. do if((c=getchar()) == '-') f = -1; while('0' > c || c > '9');
  6. do n=n*10+c-'0',c=getchar(); while('0' <= c && c <= '9');
  7. n *= f;
  8. }
  9. unsigned fix[MAXN * 20], sd = 2333;
  10. int key[MAXN * 20], s[MAXN * 20][2], sz[MAXN * 20], rt[MAXN], cnt, n, m, N, a[MAXN], num[MAXN];
  11. inline unsigned ran() { return sd = sd * sd + sd^27873; }
  12. inline void pushup(int x) {
  13. sz[x] = sz[s[x][0]] + sz[s[x][1]] + num[x];
  14. }
  15. inline void rot(int &x, bool f) {
  16. int t = s[x][f]; s[x][f] = s[t][f^1]; s[t][f^1] = x;
  17. pushup(x); pushup(t); x = t;
  18. }
  19. void Insert(int &x, int v) {
  20. if(!x) { x = ++ cnt; fix[x] = ran(); num[x] = sz[x] = 1; key[x] = v; return; }
  21. if(v == key[x]) { ++ num[x]; pushup(x); return; }
  22. bool f = key[x] < v;
  23. Insert(s[x][f], v); pushup(x);
  24. if(fix[s[x][f]] > fix[x]) rot(x, f);
  25. } int u, v, i;
  26. int Rank(int x, int v) {
  27. if(!x) return 0;
  28. if(key[x] < v) return sz[x] - sz[s[x][1]] + Rank(s[x][1], v);
  29. else if(key[x] > v) return Rank(s[x][0], v);
  30. else return sz[x] - sz[s[x][1]];
  31. }
  32. void Ins(int x, int v) {
  33. for(; x <= N; x += x&-x)
  34. Insert(rt[x], v);
  35. }
  36. int Q(int x, int y) {
  37. int sum = 0;
  38. for(; x > 0; x -= x&-x)
  39. sum += Rank(rt[x], y);
  40. return sum;
  41. }
  42. int main() {
  43. GET(n); GET(m); N = 2*n + 100000;
  44. for(int i = 1; i <= n; ++ i) {
  45. GET(a[i]); Ins(i+a[i], a[i]-i);
  46. }
  47. char op[10];
  48. for(i = 1; i <= m; ++ i) {
  49. scanf("%s", op);
  50. GET(u); GET(v);
  51. if('M' == op[0]) {
  52. a[u] = v; Ins(u+a[u], a[u]-u);
  53. }
  54. else {
  55. 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);
  56. printf("%d\n", ans);
  57. }
  58. }
  59. return 0;
  60. }

BZOJ4170 极光(CDQ分治 或 树套树)的更多相关文章

  1. BZOJ4170:极光(CDQ分治)

    Description "若是万一琪露诺(俗称rhl)进行攻击,什么都好,冷静地回答她的问题来吸引她.对方表现出兴趣的话,那就慢慢地反问.在她考虑答案的时候,趁机逃吧.就算是很简单的问题,她 ...

  2. 【Bzoj 3295】 动态逆序对(树套树|CDQ分治)

    [题意] 每次删除一个数,然后问删除前逆序对数. [分析] 没有AC不开心.. 我的树状数组套字母树,应该是爆空间的,空间复杂度O(nlogn^2)啊..哭.. 然后就没有然后了,别人家的树套树是树状 ...

  3. bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】

    模板题,折腾了许久. cqd分治整体二分,感觉像是把询问分到答案上. #include <bits/stdc++.h> #define rep(i, a, b) for (int i = ...

  4. bzoj 3295: [Cqoi2011]动态逆序对(树套树 or CDQ分治)

    Description 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计 ...

  5. [BZOJ3295][Cqoi2011]动态逆序对 CDQ分治&树套树

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j,且 ...

  6. Codechef-ANCESTOR(树套树/CDQ分治)

    题意: 给定两棵有根树,各有 N 个点.两棵树上的点分别被从 1 到 N 标号.两棵树的根均为标号为 1 的节点. 你的任务非常简单:对于每个 i,找到一个 j(j != i),使得在两棵树中 j 都 ...

  7. BZOJ 3262 cdq分治 OR 树套树

    注意判断 三个条件都一样的-- (CDQ分治 其实并不是很难理解 只是想不到--) CDQ分治: //By SiriusRen #include <cstdio> #include < ...

  8. 2019南昌网络赛-I. Yukino With Subinterval 线段树套树状数组,CDQ分治

    TMD...这题卡内存卡的真优秀... 所以以后还是别用主席树的写法...不然怎么死的都不知道... 树套树中,主席树方法开权值线段树...会造成空间的浪费...这道题内存卡的很紧... 由于树套树已 ...

  9. [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)

    题目链接 题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ CDQ+树状数组 #include<bits/stdc++.h> using nam ...

随机推荐

  1. 说说JSON和JSONP,也许你会豁然开朗(转)

    前言 由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socke ...

  2. CURLcode curl_easy_setopt(原创)

    中文翻译: curl_easy_setopt() libcurl 手册 curl_easy_setopt() 名称 curl_easy_setopt -curl的设置选项 概要 #include &l ...

  3. java 缓冲

    缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式: 二.内存缓存,也就是实现一个类中静态Map,对这个Map ...

  4. AspNetPager分页控件使用方法

    一.下载AspNetPager.dll 二.AspNetPager.dll复制于应用程序下的bin目录,打开解决方案,引用dll文件 三. 在工具栏中添加控件,这样可以支持拖拽使用 四. 要使用Asp ...

  5. JQuery源码解析--callbacks

    (function (global, factory) { factory(global); })(this, function (window, noGlobal) { var rootjQuery ...

  6. Linux下Java安装与配置

    一.卸载系统自带的JDK 如果Linux已经自带OpenJdk,我们需要将它卸载掉,否则可以直接[安装JDK] 查看Linux自带的JDK是否已安装,输入如下命令查看JAVA版本信息. java -v ...

  7. java 删除所有HTML工具类

    import java.util.regex.Matcher;import java.util.regex.Pattern; public class HtmlUtil { private stati ...

  8. IOS中无缓存的图片载入

    在IOS中,我们常用[UIImage imageNamed]方法获取图像,这种方法简便,容易理解.但是有个缺点,就是有缓存.这种方式 传人的图像的就是通过文件名方式文件名.如果,我们内存有限,我们就必 ...

  9. call_user_function()方法的使用

    call_user_func ( callback $function [, mixed $parameter [, mixed $... ]] ) 调用第一个参数所提供的用户自定义的函数. 返回值: ...

  10. 摘记 pyinstaller 使用自定义 spec

    下面的是官网的文档, 我们可以用自定义spec的方式把想要的文件打包到目标文件夹里面 例如: 我们在程序中用了一个图标 test.ico, 如果我们只用 pyinstaller -w test.py ...