题目描述

给定一个长度为n的正整数数列a[i]。
定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|。
2种操作(k都是正整数):
1.Modify x k:将第x个数的值修改为k。
2.Query x k:询问有几个i满足graze(x,i)<=k。因为可持久化数据结构的流行,询问不仅要考虑当前数列,还要
考虑任意历史版本,即统计任意位置上出现过的任意数值与当前的a[x]的graze值<=k的对数。(某位置多次修改为
同样的数值,按多次统计)

输入

第1行两个整数n,q。分别表示数列长度和操作数。
第2行n个正整数,代表初始数列。
第3--q+2行每行一个操作。

输出

对于每次询问操作,输出一个非负整数表示答案

样例输入

3 5
2 4 3
Query 2 2
Modify 1 3
Query 2 2
Modify 1 2
Query 1 1

样例输出

2
3
3


题解

KD-tree+旋转坐标系

这里的“可持久化”是逗你玩的,实际上操作只有两种:在平面上加一个点、在平面上查询到一个点曼哈顿距离不超过k的点的个数。

KD-tree就可以搞,然而这样做会TLE,因为查询斜正方形时间复杂度无法保证。

所以考虑把所有的点绕着原点逆时针旋转45度,查询的就是一个矩形空间,就可以直接使用KD-tree。

根据数学知识可知点$(x,y)$旋转后变为点$(\frac{x-y}{\sqrt 2},\frac{x+y}{\sqrt 2})$,可以把所有的$\sqrt 2$约掉,变为$(x-y,x+y)$。

查询时查的就是与某点切比雪夫距离不超过k(一个正方形范围)的点的个数。

亲测不加重构跑得比加重构还快,所以不用加了。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
int d , root , g[N];
char str[10];
struct data
{int p[2] , mx[2] , mn[2] , sum , c[2];bool operator<(data a)const {return p[d] == a.p[d] ? p[d ^ 1]< a.p[d ^ 1] : p[d] < a.p[d];}
}a[N];
void pushup(int x)
{int l = a[x].c[0] , r = a[x].c[1];a[x].mx[0] = max(a[x].p[0] , max(a[l].mx[0] , a[r].mx[0]));a[x].mx[1] = max(a[x].p[1] , max(a[l].mx[1] , a[r].mx[1]));a[x].mn[0] = min(a[x].p[0] , min(a[l].mn[0] , a[r].mn[0]));a[x].mn[1] = min(a[x].p[1] , min(a[l].mn[1] , a[r].mn[1]));a[x].sum = a[l].sum + a[r].sum + 1;
}
int build(int l , int r , int now)
{int mid = (l + r) >> 1;d = now , nth_element(a + l , a + mid , a + r + 1);a[mid].c[0] = a[mid].c[1] = 0;if(l < mid) a[mid].c[0] = build(l , mid - 1 , now ^ 1);if(r > mid) a[mid].c[1] = build(mid + 1 , r , now ^ 1);pushup(mid);return mid;
}
void insert(int &k , int x)
{if(!k) k = x;else if(a[x] < a[k]) d ^= 1 , insert(a[k].c[0] , x);else d ^= 1 , insert(a[k].c[1] , x);pushup(k);
}
int judge(int k , int x1 , int y1 , int x2 , int y2)
{if(!k || a[k].mx[0] < x1 || a[k].mx[1] < y1 || a[k].mn[0] > x2 || a[k].mn[1] > y2) return -1;if(a[k].mn[0] >= x1 && a[k].mn[1] >= y1 && a[k].mx[0] <= x2 && a[k].mx[1] <= y2) return 1;return 0;
}
int query(int k , int x1 , int y1 , int x2 , int y2)
{int tmp = judge(k , x1 , y1 , x2 , y2);if(tmp == 1) return a[k].sum;if(tmp == -1) return 0;int ans = (a[k].p[0] >= x1 && a[k].p[1] >= y1 && a[k].p[0] <= x2 && a[k].p[1] <= y2);return ans + query(a[k].c[0] , x1 , y1 , x2 , y2) + query(a[k].c[1] , x1 , y1 , x2 , y2);
}
int main()
{a[0].mx[0] = a[0].mx[1] = -1 << 30 , a[0].mn[0] = a[0].mn[1] = 1 << 30;int n , m , i , x , y;scanf("%d%d" , &n , &m);for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &g[i]) , a[i].p[0] = i - g[i] , a[i].p[1] = i + g[i];root = build(1 , n , 0);for(i = 1 ; i <= m ; i ++ ){scanf("%s%d%d" , str , &x , &y);if(str[0] == 'M') g[x] = y , a[++n].p[0] = x - y , a[n].p[1] = x + y , insert(root , n);else printf("%d\n" , query(root , x - g[x] - y , x + g[x] - y , x - g[x] + y , x + g[x] + y));}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/7124392.html

【bzoj2989】数列 KD-tree+旋转坐标系相关推荐

  1. [学习笔记] 乱世之神杀疯了 —— K-D tree

    文章目录 K-D tree 建树 合并 插入 删除 查询(估价函数) 旋转坐标系 题目练习 [SDOI2012]最近最远点对 [Violet]天使玩偶/SJY摆棋子 [CQOI2016]K远点对 [国 ...

  2. POJ3714 Raid 分治/K-D Tree

    VJ传送门 简要题意:给出两个大小均为\(N\)的点集\(A,B\),试在\(A\)中选择一个点,在\(B\)中选择一个点,使得它们在所有可能的选择方案中欧几里得距离最小,求出这个距离 下面给出的两种 ...

  3. PCL:k-d tree 1 讲解

    1.简介 kd-tree简称k维树,是一种空间划分的数据结构.常被用于高维空间中的搜索,比如范围搜索和最近邻搜索.kd-tree是二进制空间划分树的一种特殊情况.(在激光雷达SLAM中,一般使用的是三 ...

  4. K-D Tree学习笔记

    引入 K-D Tree 是一种处理高维空间的数据结构. 支持O(nk−1k)O(n^{\frac {k-1}k})O(nkk−1​)查询给定超矩形内的点的信息, kkk 为维数. 可以用替罪羊树的思想 ...

  5. HDU2966 In case of failure(浅谈k-d tree)

    嘟嘟嘟 题意:给定\(n\)个二维平面上的点\((x_i, y_i)\),求离每一个点最近的点得距离的平方.(\(n \leqslant 1e5\)) 这就是k-d tree入门题了. k-d tre ...

  6. PCL :K-d tree 2 结构理解

    K-d tree 基础思路:(先看之前的KNN思想,更容易理解) 导语:kd 树是一种二叉树数据结构,可以用来进行高效的 kNN 计算.kd 树算法偏于复杂,本篇将先介绍以二叉树的形式来记录和索引空间 ...

  7. k-d tree算法的研究

    By RaySaint 2011/10/12 动机 先前写了一篇文章<SIFT算法研究>讲了讲SIFT特征具体是如何检测和描述的,其中也提到了SIFT常见的一个用途就是物体识别,物体识别的 ...

  8. k-d tree树 近邻算法

    k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...

  9. K-d tree 算法

    转载的原文链接:http://www.cnblogs.com/eyeszjwang/articles/2429382.html 已经写得非常好了,非常清晰.只是在原文的基础上增加了一点解释,方便大家理 ...

  10. kd tree python 搜索

    海量数据最近邻查找可以用kd tree 目前理解,kd tree需要的数据维度相同,否则会出问题 kd tree实现:https://github.com/stefankoegl/kdtree 下面是 ...

最新文章

  1. 在VS2005下使用libjson -- wangj
  2. excel 插入计算机用户名,Excel中进行设置个性化用户名的操作方法
  3. 对session和cookie的一些理解
  4. LeetCode 100. 相同的树(二叉树遍历)
  5. 告别刷抖音!30秒一个Python小例子,总有一款适合你,赶紧收藏!
  6. Cisco ftp linux 权限,在Cisco设备上利用FTP传IOS文件
  7. caffe学习笔记(2)
  8. Arquillian和Jboss的版本问题
  9. Ubuntu 14.04 desktop 不能安装 openssh-server解决方法
  10. 完全卸载vs2013 2015
  11. 【软件技能】Perl 基础用法
  12. 表白公式计算机,【理工男表白公式大全】_理工男写“公式体”情书表白图
  13. 前端JS 调用 Google地图 以及拖拽地图事件触发
  14. 飘扬的旗帜!shader 编程实战!Cocos Creator!
  15. link与@import自己的一些愚见
  16. 电脑老是显示无网络连接到服务器,电脑怎么老弹出无法与服务器建立连接
  17. whistle-安卓手机配置代理
  18. 【机器学习】李宏毅-预测PM2.5
  19. LeetCode 276:栅栏涂色
  20. matlab自动对齐

热门文章

  1. Eclipse中JSP生成的class文件去了哪里?
  2. 腾讯惹谁了?为什么用QQ邮箱投简历不受人待见
  3. [MySQL][Spider][VP]Spider-3.1 VP-1.0 发布
  4. 怎么引导2岁孩子洗手问题
  5. STM32CubeMX使用(二)之串口通信
  6. [2017BUAA软工]提问回顾
  7. 【database】oracle触发器基础
  8. 如何提升会员列表数据的质量
  9. 利用wcf传递字节的简单例子
  10. PowerShell在SharePoint 2010自动化部署中的应用(1)--代码获取