题面

学习二进制分组

题目本身可以看成二维平面上的问题,转成切比雪夫距离后就是矩形和了

二进制分组是将每个修改添加到末尾,然后从后往前二进制下进位合并,这样最多同时有$\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 数列的更多相关文章

  1. [BZOJ 2989]数列(二进制分组+主席树)

    [BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...

  2. [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)

    [BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...

  3. bzoj 2989: 数列

    LINK:数列 需要动一点脑子 考虑查询 暴力显然不行 考虑把绝对值拆开. 当x<=y ax<=ay时 有 y-x+ay-ax<=k x+ax>=y+ay-k 可以发现在满足前 ...

  4. BZOJ 2989: 数列/4170: 极光

    题解: n倍经验题 首先比较容易想到的是对绝对值分类讨论 然后是4维偏序 1.查询和修改顺序 2.x>y 3.a[x]>a[y] 4.(x+a[x])-(y+a[y])<=k 这样是 ...

  5. BZOJ #2989. 数列 [树套树]

    考虑转化问题模型,这个没必要可持久化,直接加点就可以了,还不用删点 每次的问题是求 曼哈顿距离,变成切比雪夫距离然后求解 然后我们考虑将这玩意旋转 45度, 然后原坐标的 \((x,y)\) 会变成 ...

  6. bzoj 4303 数列

    bzoj 4303 数列 二维 \(KD-Tree\) 模板题. \(KD-Tree\) 虽然在更新和查询的方式上类似于线段树,但其本身定义是类似于用 \(splay/fhq\ treap\) 维护区 ...

  7. BZOJ 3142 数列(组合)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3142 题意:给出n,K,m,p.求有多少长度为K的序列A,满足:(1)首项为正整数:(2 ...

  8. BZOJ 4305: 数列的GCD( 数论 )

    对于d, 记{ai}中是d的倍数的数的个数为c, 那么有: 直接计算即可,复杂度O(NlogN+MlogM) --------------------------------------------- ...

  9. bzoj 4305 数列的GCD

    LINK:数列的GCD 题意: 给出一个长度为N的数列{a[n]},1<=a[i]<=M(1<=i<=N). 现在问题是,对于1到M的每个整数d,有多少个不同的数列b[1], ...

随机推荐

  1. 大数据入门第二十天——scala入门(二)scala基础01

    一.基础语法 1.变量类型 // 上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型.在scala是可以对数字等基础类型调用方法的. 2.变量声明——能用val的尽量使用val! ...

  2. 20155220 Exp2 后门原理与实践

    20155220 Exp2 后门原理与实践 1.Windows获得Linux Shell 在windows下,打开CMD,使用ipconfig指令查看本机IP 然后使用ncat.exe程序,ncat. ...

  3. 20155331《网络对抗》Exp5 MSF基础应用

    20155331<网络对抗>Exp5 MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode 答:exploit就是漏洞利用.exploit就是利用 ...

  4. AT24C02跨页写数据

    AT24C02 EEPROM的写数据分为:字节写数据模式和页写数据模式:字节写就是一个地址一个数据的写,页写是连续写数据,一个地址多个数据的写,但是页写不能自动跨页,如果超出一页长度,超出的数据会覆盖 ...

  5. Scala学习(一)--Scala基础学习

    Scala基础学习 摘要: 在篇主要内容:如何把Scala当做工业级的便携计算器使用,如何用Scala处理数字以及其他算术操作.在这个过程中,我们将介绍一系列重要的Scala概念和惯用法.同时你还将学 ...

  6. 配置yum,nc,telnet

    一.学习中问题 最近学习在学习Hadoop的一个子项目Zookeeper,在测试其中的“四字命令”---”echo ruok|nc localhost 2181“时发现命令无法被识别,如下图所示: [ ...

  7. Hadoop日记Day14---MapReduce源代码回顾总结

    一.回顾单词统计源码 package counter; import java.net.URI; import org.apache.hadoop.conf.Configuration; import ...

  8. Windows Defender还原误删文件

    Win 10 新版本的Windows Defender隔离/删除的文件没有还原的选项,导致被误删的文件无法在威胁记录中恢复.经过尝试发现可以通过修改注册表添加 “还原” 选项 打开注册表,找到 HKE ...

  9. 关于GitHub上传没有记录(小绿块不显示的问题)

    最近开始使用上github来上传保存自己在学习中所写过的代码,打算将自己每天的成果能有个保存,然后就利用上GitHub这么一个利器. 听说GitHub的那个绿块是用来记录每天的上传记录的,结果我将代码 ...

  10. djbc

    jdbc:mysql://localhost:3306:test这句里面分如下解析:jdbc:mysql:// 是指JDBC连接方式:localhost: 是指你的本机地址:3306 SQL数据库的端 ...