【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\)的贡献 ...
随机推荐
- 服务治理-> Spring Cloud Eureka
服务治理->搭建服务注册中心 服务治理可以说是微服务架构中最为核心和基础的模块, 它主要用来实现各个微服务 实例的自动化注册与发现. 为什么我们在微服务架构中那么需要服务治理模块呢?微服务 系统 ...
- Flink架构分析之Standalone模式启动流程
概述 FLIP6 对Flink架构进行了改进,引入了Dispatcher组件集成了所有任务共享的一些组件:SubmittedJobGraphStore,LibraryCacheManager等,为了保 ...
- ovs源码阅读--元组空间搜索算法
关于TTS(元组空间搜索算法)的详细介绍可以参考OVS+DPDK Datapath 包分类技术这篇文章,本文只对该篇博客进行简单的介绍,案例和部分图片来自于OVS+DPDK Datapath 包分类技 ...
- linux安装配置JDK脚本
#!/bin/bash # install jdk and configuring environment variables function installjdk(){ tar -zxf jdk- ...
- Tomcat java zabbix 监控
排除汤姆猫错误的步骤 ps-ef | grep java或jps –lvm 查看java pid进程 netstat –lntup | grep java 查看java 端口有没有启动 查看 tomc ...
- lastlog命令详解
基础命令学习目录首页 原文链接:https://www.cnblogs.com/qiyebao/p/4331078.html last 显示所有用户最后登录信息(会显示系统用户) last -u 50 ...
- javascript常用方法和技巧
浏览器变编辑器 data:text/html, <style type=;right:;bottom:;left:;}</style><div id="e" ...
- ModelAndView在页面上取值时value="{contextConfigLocation=<NONE>}"
后台: mv.getModel().put("initParam", 1); 页面: <input type="hidden" id="init ...
- C++ MOOC
相关课程列表: C++远征之起航篇 C++远征之离港篇 C++远征之封装篇 上 C++远征之封装篇 下 C++远征之继承篇 C++远征之多态篇 授课老师:james_yuan 在寒假,我主要选择 C+ ...
- json反序列化对象
这个是同事研究的wcf中中根据type类型反序列化json的示例 /// <summary> /// json转对象 /// </summary> /// <param ...