解题: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], ...
随机推荐
- python with原理
在python2.5+中可以用with来保证关闭打开的文件 with open('hello.txt') as f: do some file operations 为什么要引入with呢? 在之前如 ...
- WPF控件加阴影模糊问题
原文:WPF控件加阴影模糊问题 不能直接把阴影加在控件上 应该加在控件的同级兄弟节点上,覆盖在底下就不会模糊了
- libgdx学习记录10——Particle粒子
粒子对制作画面特效很有用,可以使用Particle Editor进行自行编辑粒子效果,跟图片一起生成.p粒子文件,然后导入到程序中使用. 本文所用的粒子效果是基于其自带的demo的. 实例: pack ...
- Elasticsearch date 类型详解
引言 一直对 elasticsearch 中的 date 类型认识比较模糊,而且在使用中又比较常见,这次决定多花些时间,彻底弄懂它,希望能对用到的同学提供帮助. 注意:本文测试使用是 elastics ...
- flask之jinjia2模板(二)
1.1.模板传参 (1)主程序 from flask import Flask,render_template app = Flask(__name__) @app.route('/') def he ...
- CommandoVM-虚拟机映像文件 | VM打开直接用
呵呵!自从火眼发布了这个CommandoVM,想必大家应该都挺激动,然而实际操作一下,基本炸裂-- 因为并没有给类似于kali这种直接安装的现成镜像,而是要通过github的脚本去完全网络安装 实际操 ...
- ecCodes 学习 利用ecCodes fortran90 api对GRIB文件进行读写
参考 https://www.ecmwf.int/assets/elearning/eccodes/eccodes2/story_html5.htmlhttps://confluence.ecmwf. ...
- 关于UNITY学习,给新生建议
没有不可能,只有不努力. 本人自学UNITY,实力不敢称最好,但绝对不是小白,自己独立做出过游戏,AR.(用C#) 1. 导入模型一定要注意坐标,否则会很麻烦.本人因为这个吃了很多盐 2. 学unit ...
- (转)Unity内建图标列表
用法 Gizmos.DrawIcon(transform.position, "PointLight Gizmo"); UnityEditor.EditorGUIUtility.F ...
- 在HTML中为JavaScript传递变量
在html中为JavaScript传递变量是一个关键步骤,然后就可以通过对JavaScript变量操作,实现想要达到的目的 本节代码主要使用了JavaScript中的document对象中的getEl ...