解题:BZOJ 2989 数列
学习二进制分组
题目本身可以看成二维平面上的问题,转成切比雪夫距离后就是矩形和了
二进制分组是将每个修改添加到末尾,然后从后往前二进制下进位合并,这样最多同时有$\log n$组,每个修改只会被合并$\log n$次。再用一个$log$代价在每次询问时把答案合并起来即可
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define vpii vector<pair<int,int> >
using namespace std;
const int N=,M=1e7,K=,inf=1e9;
int n,m,nm,t1,t2,pt,pw,a[N],bin[M+],vis[M+];
int root[K][N],val[M+],son[M+][]; vpii ve[];
char rd[];
void Modify(int &nde,int lst,int l,int r,int tsk)
{
nde=bin[pt--],vis[nde]=false;
val[nde]=val[lst]+;
son[nde][]=son[lst][];
son[nde][]=son[lst][];
if(l==r) return; int mid=(l+r)>>;
if(tsk<=mid) Modify(son[nde][],son[lst][],l,mid,tsk);
else Modify(son[nde][],son[lst][],mid+,r,tsk);
}
void Delete(int nde,int l,int r)
{
if(vis[nde]) return;
bin[++pt]=nde,vis[nde]=true;
int mid=(l+r)>>;
Delete(son[nde][],l,mid);
Delete(son[nde][],mid+,r);
val[nde]=son[nde][]=son[nde][]=;
}
void Insert(int x,int y)
{
ve[++pw].push_back(make_pair(x,y));
Modify(root[pw][],root[pw][],,nm,y);
while(pw>&&ve[pw].size()==ve[pw-].size())
{
int t1=,t2=,sz=ve[pw].size(); vpii tmp;
for(int i=;i<=sz;i++) Delete(root[pw][i],,nm);
for(int i=;i<=sz;i++) Delete(root[pw-][i],,nm);
while(t1<sz||t2<sz)
if(t1<sz&&(t2==sz||ve[pw-][t1]<ve[pw][t2]))
tmp.push_back(ve[pw-][t1++]),Modify(root[pw-][t1+t2],root[pw-][t1+t2-],,nm,ve[pw-][t1-].second);
else
tmp.push_back(ve[pw][t2++]),Modify(root[pw-][t1+t2],root[pw-][t1+t2-],,nm,ve[pw][t2-].second);
ve[pw-]=tmp,ve[pw--].clear();
}
}
int Ask(int nl,int nr,int l,int r,int ll,int rr)
{
if(l>=ll&&r<=rr)
return val[nr]-val[nl];
else
{
int ret=,mid=(l+r)>>;
if(mid>=ll) ret+=Ask(son[nl][],son[nr][],l,mid,ll,rr);
if(mid<rr) ret+=Ask(son[nl][],son[nr][],mid+,r,ll,rr);
return ret;
}
}
int Query(int x,int y,int k)
{
int ret=;
for(int i=;i<=pw;i++)
{
int ll=lower_bound(ve[i].begin(),ve[i].end(),make_pair(x-k,))-ve[i].begin();
int rr=lower_bound(ve[i].begin(),ve[i].end(),make_pair(x+k,inf))-ve[i].begin();
ret+=Ask(root[i][ll],root[i][rr],,nm,max(y-k,),min(y+k,nm));
}
return ret;
}
int main()
{
scanf("%d%d",&n,&m);
vis[]=true,nm=;
for(int i=;i<=M;i++)
bin[++pt]=i,vis[i]=true;
for(int i=;i<=n;i++)
scanf("%d",&a[i]),Insert(a[i]+i,a[i]-i+n);
for(int i=;i<=m;i++)
{
scanf("%s%d%d",rd,&t1,&t2);
if(rd[]=='M') a[t1]=t2,Insert(t2+t1,t2-t1+n);
else printf("%d\n",Query(a[t1]+t1,a[t1]-t1+n,t2));
}
return ;
}
解题:BZOJ 2989 数列的更多相关文章
- [BZOJ 2989]数列(二进制分组+主席树)
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- bzoj 2989: 数列
LINK:数列 需要动一点脑子 考虑查询 暴力显然不行 考虑把绝对值拆开. 当x<=y ax<=ay时 有 y-x+ay-ax<=k x+ax>=y+ay-k 可以发现在满足前 ...
- BZOJ 2989: 数列/4170: 极光
题解: n倍经验题 首先比较容易想到的是对绝对值分类讨论 然后是4维偏序 1.查询和修改顺序 2.x>y 3.a[x]>a[y] 4.(x+a[x])-(y+a[y])<=k 这样是 ...
- BZOJ #2989. 数列 [树套树]
考虑转化问题模型,这个没必要可持久化,直接加点就可以了,还不用删点 每次的问题是求 曼哈顿距离,变成切比雪夫距离然后求解 然后我们考虑将这玩意旋转 45度, 然后原坐标的 \((x,y)\) 会变成 ...
- bzoj 4303 数列
bzoj 4303 数列 二维 \(KD-Tree\) 模板题. \(KD-Tree\) 虽然在更新和查询的方式上类似于线段树,但其本身定义是类似于用 \(splay/fhq\ treap\) 维护区 ...
- BZOJ 3142 数列(组合)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3142 题意:给出n,K,m,p.求有多少长度为K的序列A,满足:(1)首项为正整数:(2 ...
- BZOJ 4305: 数列的GCD( 数论 )
对于d, 记{ai}中是d的倍数的数的个数为c, 那么有: 直接计算即可,复杂度O(NlogN+MlogM) --------------------------------------------- ...
- bzoj 4305 数列的GCD
LINK:数列的GCD 题意: 给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N). 现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], ...
随机推荐
- 大数据入门第二十四天——SparkStreaming(一)入门与示例
一.概述 1.什么是spark streaming Spark Streaming is an extension of the core Spark API that enables scalabl ...
- VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法
原文:VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/ar ...
- HTML基础之JS
HTML中的三把利器的JS 又称为JavaScript,看着好像和Java有点联系,实际上他和java半毛钱关系都没有,JavaScript和我们学习的Python.Go.Java.C++等,都是一种 ...
- node.js学习笔记(四)——EventEmitter
error 事件 EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到异常的时候通常会触发 error 事件.当 error 被触发时,EventEmitter ...
- chrome浏览器插件 Octotree 让你浏览GitHub的时候像IDE 一样提供项目目录
GitHub 作为代码托管平台,竟然没有提供项目目录,方便用户在线快速浏览项目结构.所以,在线分析项目源码就会变得很繁琐,必须一层一层点击,然后再一次一次地向上返回.要知道,本来 GitHub 网站在 ...
- eclipse中设置项目的编码方式
1.windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Workspace,右侧Text file encoding ...
- FINAUNCE金融业增速反弹信贷投放创新高叠加股市回暖
FINAUNCE金融业增速反弹信贷投放创新高叠加股市回暖,金融业增加值增速回暖,不过难以回到2015年的巅峰. 国家统计局4月18日发布的数据显示,今年一季度,国内生产总值21.34万亿元,按可比价格 ...
- 使用开源项目免费申请 JetBrains 全家桶 IDEA 开源许可证
JetBrains 公司旗下的 IDEA 功能都十分强大,深受各种编程语言相关的程序员的喜爱.我个人而言,经常使用 WebStorm,也使用过 PyCharm. 正常情况下 JetBrains 公司的 ...
- PAT-1045. Favorite Color Stripe (30)-LIS
将Eva喜欢的颜色按顺序编个优先级, 2 3 1 5 6-> 1 2 3 4 5 然后读取stripe,将Eva不喜欢的先剔除掉,剩下的颜色替换为相应的优先级 2 2 4(去掉) 1 5 5 6 ...
- 《Linux内核设计与实现》Chapter 1 读书笔记
<Linux内核设计与实现>Chapter 1 读书笔记 一.Unix的特点 Unix从Multics中产生,是一个强大.健壮和稳定的操作系统. 特点 1.很简洁 2.在Unix系统中,所 ...