[BZOJ]4170: 极光 2989: 数列 CDQ分治+树状数组
来源:互联网 发布:极速淘宝秒杀 编辑:程序博客网 时间:2024/05/22 01:45
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的对数。(某位置多次修改为同样的数值,按多次统计)
题解:
一开始看,分四种情况讨论的话是四维偏序,后来灵机一动,把它看做平面上的点的话,求的就是距离不超过k的有多少个点,这个区域恰好是一个菱形,那么把坐标系旋转一下,就可以变成询问一个矩形内数的和了,那么就和简单题的方法一样了。(不知道为什么数组要莫名开大)
代码:
#include<bits/stdc++.h>using namespace std;#define LL long longconst int Maxq=150010;int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*f;}int n,Q,a[600100],cnt,idcnt=0;int X(int x,int y){return x+y-1;}int Y(int x,int y){return n-x+y;}LL ans[500100];struct Opt{int x,y,k,type,id;}q[Maxq],q1[Maxq<<2],temp[Maxq<<2];int s[4000010];void add(int x,int y){if(x<=0)return;for(;x<=4000000;x+=(x&-x))s[x]+=y;}LL getsum(int x){LL re=0;for(;x>0;x-=(x&-x))re+=(LL)(s[x]);return re;}int List[Maxq<<2];void solve(int l,int r){ if(l==r)return; int mid=l+r>>1; solve(l,mid);solve(mid+1,r); int i=l,j=mid+1,len=0,o=0; while(i<=mid&&j<=r) { if(q1[i].x<q1[j].x||(q1[i].x==q1[j].x&&q1[i].type<q1[j].type)) { if(q1[i].type==1)add(q1[i].y,1),List[++o]=q1[i].y; temp[++len]=q1[i++]; } else { if(q1[j].type==2)ans[q1[j].id]+=getsum(q1[j].y); else if(q1[j].type==3)ans[q1[j].id]-=getsum(q1[j].y); temp[++len]=q1[j++]; } } int t=i; while(i<=mid)temp[++len]=q1[i++]; while(j<=r) { if(q1[j].type==2)ans[q1[j].id]+=getsum(q1[j].y); else if(q1[j].type==3)ans[q1[j].id]-=getsum(q1[j].y); temp[++len]=q1[j++]; } for(int p=1;p<=o;p++)add(List[p],-1); for(int p=1;p<=len;p++)q1[l+p-1]=temp[p];}int main(){ n=read(),Q=read(); for(int i=1;i<=n;i++)q[i].type=1,q[i].x=i,q[i].y=a[i]=read(); for(int i=1;i<=Q;i++) { char op[8]; scanf("%s",op); int u1=read(),u2=read(),t=i+n; if(op[0]=='M')q[t].type=1,q[t].x=u1,q[t].y=u2,a[u1]=u2; else q[t].type=2,q[t].x=u1,q[t].y=a[u1],q[t].k=u2,q[t].id=++idcnt; } for(int i=1;i<=n;i++)q1[i]=q[i],q1[i].x=X(q[i].x,q[i].y),q1[i].y=Y(q[i].x,q[i].y);cnt=n; for(int i=1+n;i<=Q+n;i++) { if(q[i].type==1)q1[++cnt]=q[i],q1[cnt].x=X(q[i].x,q[i].y),q1[cnt].y=Y(q[i].x,q[i].y); else { int X1=q[i].x,Y1=q[i].y-q[i].k,X2=q[i].x,Y2=q[i].y+q[i].k; int x1=X(X1,Y1),y1=Y(X1,Y1),x2=X(X2,Y2),y2=Y(X2,Y2); q1[++cnt].type=2;q1[cnt].x=x2;q1[cnt].y=y2; q1[++cnt].type=2;q1[cnt].x=x1-1;q1[cnt].y=y1-1; q1[++cnt].type=3;q1[cnt].x=x1-1;q1[cnt].y=y2; q1[++cnt].type=3;q1[cnt].x=x2;q1[cnt].y=y1-1; q1[cnt].id=q1[cnt-1].id=q1[cnt-2].id=q1[cnt-3].id=q[i].id; } } solve(1,cnt); for(int i=1;i<=idcnt;i++)printf("%lld\n",ans[i]);}
阅读全文
2 0
- [BZOJ]4170: 极光 2989: 数列 CDQ分治+树状数组
- 【bzoj2989】【数列】【cdq分治+树状数组】
- BZOJ 2683 简单题 CDQ分治+树状数组
- BZOJ 2244 SDOI2011 拦截导弹 CDQ分治/二维树状数组
- BZOJ 2683 简单题 cdq分治+树状数组
- 【BZOJ 3262】陌上花开(CDQ分治+树状数组)
- 【bzoj 1176】[Balkan2007] Mokia(cdq分治+树状数组)
- bzoj 3295: [Cqoi2011]动态逆序对 cdq分治+树状数组
- bzoj 2738: 矩阵乘法 cdq分治+二维树状数组
- bzoj 2683: 简单题 cdq分治+树状数组
- BZOJ 2683: 简单题【CDQ分治 + 树状数组
- BZOJ 1176: [Balkan2007]Mokia【CDQ分治+树状数组
- 【BZOJ 2683】简单题 CDQ分治+树状数组
- bzoj 2683: 简单题 (CDQ分治+树状数组)
- bzoj 4553: [Tjoi2016&Heoi2016]序列 cdq分治+树状数组
- bzoj 2527: [Poi2011]Meteors cdq分治+树状数组
- BZOJ 1176 [Balkan2007]Mokia [CDQ分治+树状数组]
- [BZOJ]3262: 陌上花开 CDQ分治+树状数组
- Microsoft SilverLight
- 一些经典的面试题
- div模拟输入框
- 自顶而下,逐步求精
- plsql调试存储过程单步不能进入断点
- [BZOJ]4170: 极光 2989: 数列 CDQ分治+树状数组
- 鼠标移动到Chart控件图表数据点处,显示相关信息
- win10 VPN里的ipv4的属性打不开,没办法去掉勾选“在远程网络上使用默认网关”如何解决?
- document.cookie与request.cookie
- 大学生毕业4年后转行,在郑州传智播客为未来努力
- mysql5.7官网直译SQL语句优化--子查询,派生表和试图引用
- FlowLayout实现自定义的流式布局
- 顺序栈使用——括号匹配的检验
- spring整合JNDI和Tomcat