[JZOJ3615]【NOI2014模拟】数列(平面几何+二维线段树)
Description
给定一个长度为n的正整数数列a[i]。
定义2个位置的f值为两者位置差与数值差的和,即f(x,y)=|x-y|+|a[x]-a[y]|。
你需要写一个程序支持2种操作(k都是正整数):
Modify x k:将第x个数的值修改为k。
Query x k:询问有几个i满足f(x,i)<=k。询问不仅要考虑当前数列,还要考虑任意历史版本,即统计任意位置上出现过的任意数值与当前的a[x]的f值<=k的对数。(某位置多次修改为同样的数值,按多次统计)
Main
令F(x,y)=|x-y|+|a[x]-a[y]|,每次可以将a[x]修改为k,或者查询满足f(x,i)≤k的个数。
Analysis
【二维线段树/树状数组】
  看到题目这样的粗俗,笼统,简洁明了,便知道一定要用一个数据结构维护
我们可以将x抽象为x坐标,a[x]抽象为y坐标,那么f(x,y)的意思就显然了:表示x点(x,a[x])和y点(y,a[y])的曼哈顿距离。
但是这个曼哈顿距离比较蛋疼,不着急,画(截)个图看看。
  
我们发现图片大概是这样的,发现这个可以取的范围是个菱形,旋转90°就变成了正方形。旋转就是使坐标(x,y)变成(x+y,x-y)
  
那么,问题就转化为每次可以加入一些点,求某个正方形内包含点的个数。
【K-Dtree】
。。。
【cbq分治+主席树】
...
Solution
我们考虑用一个数据结构来维护,如二维线段树/树状数组。
每次相当于插入点(x+a[x],x-a[x])到图中,线段树/树状数组维护左下角为(x1,y1),右上角为(x2,y2)的矩阵信息,查询即可。
对于二维线段树,有两种实现方法。一种是划分为4个区域,第二种是划分为2个,根据长宽的大小来切。
  

要动态开点。直接做会超时,要加优化:当前子树没有贡献,直接退出。
【K-Dtree】
。。。
【cbq分治+主席树】
...
Code
{$inline on}
var
        ch,lala:char;
        n,m,i,x,y,tot,ans:longint;
        a:array[..] of longint;
        tree:array[..] of longint;
        son:array[..,..] of longint;
procedure dispose; inline;
begin
        read(ch);
        lala:='';
        while lala<>' ' do read(lala);
        readln(x,y);
end;
procedure fyj(x:longint); inline;
begin
        if son[x,]= then
        begin
                inc(tot); son[x,]:=tot;
                inc(tot); son[x,]:=tot;
        end;
end;
procedure change(root,x1,y1,x2,y2,fx,fy:longint);  inline;
var
        mid:longint;
begin
        if (x1=x2) and (y1=y2) and (x1=fx) and (y1=fy) then
        begin
                inc(tree[root]);
                exit;
        end;
        fyj(root);
        if x2-x1>=y2-y1 then
        begin
                mid:=(x1+x2) shr ;
                if fx<=mid then
                        change(son[root,],x1,y1,mid,y2,fx,fy)
                else
                        change(son[root,],mid+,y1,x2,y2,fx,fy);
        end
        else
        begin
                mid:=(y1+y2) shr ;
                if fy<=mid then
                        change(son[root,],x1,y1,x2,mid,fx,fy)
                else
                        change(son[root,],x1,mid+,x2,y2,fx,fy);
        end;
        tree[root]:=tree[son[root,]]+tree[son[root,]];
end;
procedure find(root,x1,y1,x2,y2,fx1,fy1,fx2,fy2:longint);  inline;
var
        mid:longint;
begin
        if (x1=fx1) and (x2=fx2) and (y1=fy1) and (y2=fy2) then
        begin
                ans:=ans+tree[root];
                exit;
        end;
        if son[root,]= then
                exit;
        if x2-x1>=y2-y1 then
        begin
                mid:=(x1+x2) shr ;
                if fx2<=mid then
                        find(son[root,],x1,y1,mid,y2,fx1,fy1,fx2,fy2)
                else
                if fx1>mid then
                        find(son[root,],mid+,y1,x2,y2,fx1,fy1,fx2,fy2)
                else
                begin
                        find(son[root,],x1,y1,mid,y2,fx1,fy1,mid,fy2);
                        find(son[root,],mid+,y1,x2,y2,mid+,fy1,fx2,fy2);
                end;
        end
        else
        begin
                mid:=(y1+y2) shr ;
                if fy2<=mid then
                        find(son[root,],x1,y1,x2,mid,fx1,fy1,fx2,fy2)
                else
                if fy1>mid then
                        find(son[root,],x1,mid+,x2,y2,fx1,fy1,fx2,fy2)
                else
                begin
                        find(son[root,],x1,y1,x2,mid,fx1,fy1,fx2,mid);
                        find(son[root,],x1,mid+,x2,y2,fx1,mid+,fx2,fy2);
                end;
        end;
end;
begin
        readln(n,m);
        tot:=;
        for i:= to n do
        begin
                read(a[i]);
                change(,,,,,i+a[i]+,i-a[i]+);
        end;
        readln;
        for i:= to m do
        begin
                dispose;
                if ch='M' then
                begin
                        change(,,,,,x+y+,x-y+);
                        a[x]:=y;
                end
                else
                begin
                        ans:=;
                        find(,,,,,x+a[x]-y+,x-a[x]-y+,x+a[x]+y+,x-a[x]+y+);
                        writeln(ans);
                end;
        end;
end.
[JZOJ3615]【NOI2014模拟】数列(平面几何+二维线段树)的更多相关文章
- [CSP-S模拟测试]:表格(动态开点二维线段树+离散化)
		题目传送门(内部题112) 输入格式 一个数$N$,表示矩形的个数. 接下来$N$行,每行四个整数$X_a,Y_a,X_b,Y_b$.分别表示每个矩形左下角和右上角的坐标. 保证$(X_a<X_ ... 
- poj 1195:Mobile phones(二维线段树,矩阵求和)
		Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ... 
- bzoj4785:[ZJOI2017]树状数组:二维线段树
		分析: "如果你对树状数组比较熟悉,不难发现可怜求的是后缀和" 设数列为\(A\),那么可怜求的就是\(A_{l-1}\)到\(A_{r-1}\)的和(即\(l-1\)的后缀减\( ... 
- UVA 11297 线段树套线段树(二维线段树)
		题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ... 
- POJ2155 Matrix二维线段树经典题
		题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ... 
- HDU 1823 Luck and Love(二维线段树)
		之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ... 
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
		Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ... 
- POJ 2155 Matrix (二维线段树)
		Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ... 
- HDU 4819 Mosaic (二维线段树)
		Mosaic Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ... 
随机推荐
- Exp5 MSF基础应用 20164314
			一.实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 1.一个主动攻击实践,如ms08_067; (成功) 2.一个针对浏览器的攻击,如ms1 ... 
- C# 处理文件,视频,音频,压缩包下载
			文章介绍了通过HttpWebRequest和HttpWebResponse实现视频下载的功能:首先HttpWebRequest类利用HTTP 协议和服务器交互,再由HttpWebResponse返回来 ... 
- css21规范学习
			https://www.w3.org/TR/CSS22 1. An asterisk (*) indicates that the preceding type, word, or group occ ... 
- 安卓触控一体机的逆袭之路_追逐品质_支持APP软件安卓
			显示性能参数 接口:RGB信号 分辨率:1024*600 比例16:9 显示尺寸(A.A.):222.72*(W)*125.28(H)mm 外围尺寸:235.0(W)*143.0(H)*4.5(T)m ... 
- window10:jdk 8下载和安装步骤
			window10:jdk 8下载和安装步骤 点击链接:https://blog.csdn.net/qq_39720249/article/details/80721719 
- gradle 编译 "aapt.exe'' finished with non-zero exit value 1 问题
			升级了一下android studio的版本,从3.0升级到3.3,升级过后,编译确实快了不少,但项目导入后一直报 "aapt.exe'' finished with non-zero ex ... 
- osgearth介绍
			osgEarth为开发osg应用提供了一个地理空间SDK和地形引擎. osgEarth的目标: l 提供基于osg开发3D地理空间应用的支持; l 直接从数据源可视化地形模型和影像变得更加简单: l ... 
- WPF入门之一APP.XAML
			WPF运行之后,App.xaml是应用的声明起始点. 一.指定入口 通过指定Application 的StartupUri属性,指示了启动应用的时候,加载哪个窗口或网页. 最常见的就是将默认的Main ... 
- asp.net core 学习资料整理
			net上海俱乐部 白手套大神分享 广州一位大佬总结的系列文章 https://www.cnblogs.com/viter/p/10474091.html 汪宇杰 http://edi.wan ... 
- mathJax基础语法-0基础开始,(这是网上抄来的如果有权限和版权问题联系本人处理,仅供学术参考)
