【BZOJ2989】数列(CDQ分治,扫描线)
【BZOJ2989】数列(CDQ分治)
题面
BZOJ
权、。、。、权限题。。
题解
Description
给定一个长度为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的对数。(某位置多次修改为
同样的数值,按多次统计)
Input
第1行两个整数n,q。分别表示数列长度和操作数。
第2行n个正整数,代表初始数列。
第3--q+2行每行一个操作。
Output
对于每次询问操作,输出一个非负整数表示答案
Sample Input
3 5
2 4 3
Query 2 2
Modify 1 3
Query 2 2
Modify 1 2
Query 1 1
Sample Output
2
3
3
HINT
N<=60000 修改操作数<=40000 询问<=50000 Max{a[i]}含修改<=100000
题解
很容易想到把数列上的每一个点看成平面上的一个点,
那么题目中给定的限制变成了求距离一个点的曼哈顿距离在一个范围内的点。
很明显,这个区域在平面上是一个菱形,旋转\(45°\)之后就成为了一个正方形。
对于一个点\((x,y)\),旋转\(45°\)的方法是变成\((x+y,x-y)\),
那么询问曼哈顿距离不超过\(k\)就变成了询问矩形\(([x+y-k,x+y+k],[x-y-k,x-y+k])\)内的点数。
那么,问题变成了,加入一个点,查询一个矩形内的点数,
直接\(CDQ\)分治,然后扫描线统计答案就好了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define MAX 500100
#define py 250050
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int c[MAX];
int lb(int x){return x&(-x);}
void modify(int x,int w){while(x<MAX)c[x]+=w,x+=lb(x);}
int getsum(int x){int ret=0;while(x)ret+=c[x],x-=lb(x);return ret;}
int getsum(int l,int r){return getsum(r)-getsum(l-1);}
int n,Q,a[MAX],ans[MAX];
char ch[10];
struct Opt{int opt,x,y,d,id;}p[MAX],tmp[MAX];
bool operator<(Opt a,Opt b){if(a.x!=b.x)return a.x<b.x;return a.opt>b.opt;}
int tot,cnt;
void CDQ(int l,int r)
{
if(l==r)return;int mid=(l+r)>>1,t=0;
for(int i=l;i<=mid;++i)if(!p[i].opt)tmp[++t]=p[i];
for(int i=mid+1;i<=r;++i)
{
if(!p[i].opt)continue;
tmp[++t]=(Opt){+1,p[i].x-p[i].d,p[i].y,p[i].d,p[i].id};
tmp[++t]=(Opt){-1,p[i].x+p[i].d,p[i].y,p[i].d,p[i].id};
}
sort(&tmp[1],&tmp[t+1]);
for(int i=1;i<=t;++i)
if(tmp[i].opt==0)modify(tmp[i].y,1);
else ans[tmp[i].id]-=tmp[i].opt*getsum(tmp[i].y-tmp[i].d,tmp[i].y+tmp[i].d);
for(int i=1;i<=t;++i)if(tmp[i].opt==0)modify(tmp[i].y,-1);
CDQ(l,mid);CDQ(mid+1,r);
}
int main()
{
n=read();Q=read();
for(int i=1;i<=n;++i)a[i]=read(),p[++tot]=(Opt){0,i+a[i]+py,i-a[i]+py,0,0};
for(int i=1;i<=Q;++i)
{
scanf("%s",ch);
if(ch[0]=='Q')
{
int x=read();
p[++tot]=(Opt){1,x+a[x]+py,x-a[x]+py,read(),++cnt};
}
else
{
int x=read();a[x]=read();
p[++tot]=(Opt){0,x+a[x]+py,x-a[x]+py,0,0};
}
}
CDQ(1,tot);
for(int i=1;i<=cnt;++i)printf("%d\n",ans[i]);
return 0;
}
【BZOJ2989】数列(CDQ分治,扫描线)的更多相关文章
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- 【LOJ2586】【APIO2018】选圆圈 CDQ分治 扫描线 平衡树
题目描述 在平面上,有 \(n\) 个圆,记为 \(c_1,c_2,\ldots,c_n\) .我们尝试对这些圆运行这个算法: 找到这些圆中半径最大的.如果有多个半径最大的圆,选择编号最小的.记为 \ ...
- 【BZOJ4285】使者 cdq分治+扫描线+树状数组
[BZOJ4285]使者 Description 公元 8192 年,人类进入星际大航海时代.在不懈的努力之下,人类占领了宇宙中的 n 个行星,并在这些行星之间修建了 n - 1 条星际航道,使得任意 ...
- Bzoj2683 简单题 [CDQ分治]
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1071 Solved: 428 Description 你有一个N*N的棋盘,每个格子内有一个整数, ...
- COGS 577 蝗灾 [CDQ分治入门题]
题目链接 昨天mhr神犇,讲分治时的CDQ分治的入门题. 题意: 你又一个w*w正方形的田地. 初始时没有蝗虫. 给你两个操作: 1. 1 x y z: (x,y)这个位置多了z只蝗虫. 2. 2 x ...
- HDU 3507 Print Article(CDQ分治+分治DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp ...
- BZOJ1173 CDQ分治 笔记
目录 二维数据结构->cdq 预备知识 T1: 二维树状数组 T2:cdq分治 bzoj1176 mokia:Debug心得 一类特殊的CDQ分治 附: bzoj mokia AC代码 二维数据 ...
- N维偏序:cdq分治
cdq(陈丹琦)分治,是一种类似二分的算法.基本思想同分治: 递归,把大问题划分成若干个结构相同的子问题,直到(L==R): 处理左区间[L,mid]对右区间[mid+1,R]的影响: 合并. 它可以 ...
- Codeforces 848C Goodbye Souvenir [CDQ分治,二维数点]
洛谷 Codeforces 这题我写了四种做法-- 思路 不管做法怎样,思路都是一样的. 好吧,其实不一样,有细微的差别. 第一种 考虑位置\(x\)对区间\([l,r]\)有\(\pm x\)的贡献 ...
随机推荐
- 一个很NB的404页面
一个带彩蛋的 404 页面 不得不说这个程序猿很有才 前往404页面 触发方法 按住鼠标左键 在页面中心不停的画圈 就可以进入神奇的地方了
- Python模块搜索路径
当一个名为 spam 的模块被导入的时候,解释器首先寻找具有该名称的内置模块.如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找名为 spam.py 的文件.sys.path 初始 ...
- HDFS文件系统基础
HDFS架构实现 Hadoop当前稳定版本是Apache Hadoop 2.9.2,最新版本是Apache Hadoop 3.1.1. http://hadoop.apache.org/docs/ H ...
- Annotation 使用备忘2
title: Annotation 使用备忘 date: 2018-01-02 20:48:43 tags: [Annotation] categories: [Programming,Java] - ...
- Bootstrap学习--基本格式
以下为Bootstrap的基本格式代码 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta ...
- HotSpot JVM 常用配置设置
本文讨论的选项是针对HotSpot虚拟机的. 1.选项分类及语法 HotspotJVM提供以下三大类选项: 1.1.标准选项 这类选项的功能是很稳定的,在后续版本中也不太会发生变化. 运行java或者 ...
- 局域网传输-LED灯搭建局域网:数据传输可达每秒3Gb
一 : LED灯搭建局域网:数据传输可达每秒3Gb 我们之前介绍了利用可见光通讯技术,通过LED灯光实现精准室内定位的例子.实际上,这种灯泡和技术的用途不止于此,比如,它还能进行无线网络传输. 最近, ...
- Task 6.2站立会议二
今天,我们开始自己开始编译运行代码了,服务器端,聊天界面的相关代码经过测试.大家都把自己的实验过程公布了,大家的交流对实验的进度也起到了很大的作用.明天我们要继续修改实验中的错误,然后大家一起把实验基 ...
- dazhewang数据库初设计
mysql> use dazhe; Database changed mysql> create table shops(id int primary key auto_increment ...
- [二叉树建树&完全二叉树判断] 1110. Complete Binary Tree (25)
1110. Complete Binary Tree (25) Given a tree, you are supposed to tell if it is a complete binary tr ...