【bzoj2989】【数列】【cdq分治+树状数组】
来源:互联网 发布:作头部ct的危害知乎 编辑:程序博客网 时间:2024/05/24 07:07
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
2 4 3
Query 2 2
Modify 1 3
Query 2 2
Modify 1 2
Query 1 1
Sample Output
2
3
3
3
3
HINT
N<=60000 修改操作数<=40000 询问<=50000 Max{a[i]}含修改<=100000
题解:
首先可以发现所谓的可持久化看成加点即可.
把(x,a[x])看成一个点.然后我们把曼哈顿距离转化成切比雪夫距离.
问题就变成了每次询问一个矩形中有多少点.
把一个矩形拆成4个然后cdq分治+树状数组即可.
注意坐标不一定都在第一象限,拆分矩形的时候判断一下即可.
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cstdio>#include<algorithm>#define N 100010#define M 200010using namespace std;int n,m,a[N],tot,x,y,k,cnt,mx,t[M<<2],ans[M];char ch[10]; struct use{int x,y,id,k,v,p;}q[M<<2],p[M<<2];int read(){ int x(0);char ch=getchar(); while(ch<'0'||ch>'9') ch=getchar(); while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x; }void add(int kind,int p,int x,int y){ int xx=x-y,yy=x+y;mx=max(yy,mx);//cout<<xx<<' '<<yy<<endl; if (kind==0){q[++tot].x=xx;q[tot].y=yy;q[tot].id=tot;q[tot].k=kind;} else{ int x1=xx-k,y1=yy-k,x2=xx+k,y2=yy+k;mx=max(mx,y2); if (y1>0){q[++tot].id=tot;q[tot].k=kind;q[tot].x=x1-1;q[tot].y=y1-1;q[tot].v=1;q[tot].p=p;} q[++tot].id=tot;q[tot].k=kind;q[tot].x=x1-1;q[tot].y=y2;q[tot].v=-1;q[tot].p=p; if (y1>0){q[++tot].id=tot;q[tot].k=kind;q[tot].x=x2;q[tot].y=y1-1;q[tot].v=-1;q[tot].p=p;} q[++tot].id=tot;q[tot].k=kind;q[tot].x=x2;q[tot].y=y2;q[tot].v=1;q[tot].p=p; }}bool cmp(use a,use b){ if (a.x==b.x){ if (a.y==b.y) return a.id<b.id; else return a.y<b.y; } return a.x<b.x;}int lowbit(int x){return x&(-x);}void add(int x,int v){for (int i=x;i<=mx;i+=lowbit(i)) t[i]+=v;}int query(int x){ int ans(0); for (int i=x;i;i-=lowbit(i)) ans+=t[i]; return ans;}void solve(int l,int r){ if (l==r) return; int mid=(l+r)>>1,l1=l,l2=mid+1; for (int i=l;i<=r;i++){ if (q[i].id<=mid&&!q[i].k) add(q[i].y,1); if (q[i].id>mid&&q[i].k) ans[q[i].p]+=query(q[i].y)*q[i].v; } for (int i=l;i<=r;i++) if (q[i].id<=mid&&!q[i].k) add(q[i].y,-1); for (int i=l;i<=r;i++) if (q[i].id<=mid) p[l1++]=q[i]; else p[l2++]=q[i]; for (int i=l;i<=r;i++) q[i]=p[i]; solve(l,mid);solve(mid+1,r);}int main(){ n=read();m=read(); for (int i=1;i<=n;i++) a[i]=read(),add(0,0,i,a[i]); for (int i=n+1;i<=n+m;i++){ scanf("%s",ch); if (ch[0]=='M') x=read(),y=read(),add(0,0,x,y),a[x]=y; else x=read(),k=read(),add(1,++cnt,x,a[x]); } sort(q+1,q+tot+1,cmp);mx++; solve(1,tot); for (int i=1;i<=cnt;i++) printf("%d\n",ans[i]); }
0 0
- 【bzoj2989】【数列】【cdq分治+树状数组】
- [BZOJ]4170: 极光 2989: 数列 CDQ分治+树状数组
- BZOJ1176【CDQ分治】【树状数组】
- [BZOJ1176][Balkan2007]Mokia && CDQ分治+树状数组
- COGS 577 蝗灾 cdq分治+树状数组
- HDU 5126 stars cdq分治+树状数组
- hdu 5126 stars ( CDQ分治 + 树状数组)
- BZOJ_P1176 [Balkan2007]Mokia(CDQ分治+树状数组)
- BZOJ_P3262 陌上花开(CDQ分治+树状数组)
- HDU 5618 (CDQ分治 树状数组)
- HDU 4742 (CDQ分治 树状数组)
- HDU 5324 (CDQ分治 树状数组)
- HDU - 5618 CDQ分治 + 树状数组
- 【bzoj3262】陌上花开 CDQ分治+树状数组
- 【bzoj2683】简单题 CDQ分治+树状数组
- [CDQ分治] [树状数组] [BZOJ3262] 陌上花开
- 数据(CDQ分治+树状数组)
- [BZOJ2683&&BZOJ1176] CDQ分治&&树状数组
- xcode怎么更换app的图标和名字?
- Cocosd2d 实现图像描边shader
- CSS3动画(个人理解)
- java线程
- My97DatePicker设置,包括隐藏 清空,设置最大日期等
- 【bzoj2989】【数列】【cdq分治+树状数组】
- 【UI】【View】MotionEvent类详解
- Linux下同时打开编辑多个文件 【VSP、vim -o】
- 3、关于DST
- 创建母版页导致js出现“ 'document.getElementById(...)' 为空或不是对象”错误
- IOS 调试技巧 查看View的视图结构
- 增加phpmyadmin导入文件上限
- python修改编码方式
- 对前端框架的思考和理解