bzoj-1901 Dynamic Rankings

来源:互联网 发布:淘宝投诉成立 编辑:程序博客网 时间:2024/06/13 23:21

题意:

带修改区间k小值;

n,m<=10000;

a[i]<=10^9;


题解:

听说是道裸题就过来刷刷 (卧槽我最近似乎都是在刷裸题);

写完前缀和的主席树感觉挺厉害,感受了一下树状数组就来写这题;

然后写更新的的时候我就不会了;

前缀和的时候,后一个树从前一个继承一部分结点而来的;

但是树状数组不能这么搞啊= =;

然后发现暴力建就可以了,也是犯二了;

最多n+m次修改,每次修改logn棵线段树,每颗线段树最多增加log(n+m)个结点;

空间也就是O(nlog2n),所以没问题;

修改算是搞过了,查询大概就主席树一下,加上树状数组的复杂度是log2n的;

跑的飞快,328ms  (其实我一开始脑抽写成了O(nlog3n)然而还是500ms+);


代码:


#include<vector>#include<stdio.h>#include<string.h>#include<algorithm>#define N 11000using namespace std;struct node{int l,r,sum;}a[N<<8];vector<int>nol,nor;int dis[N<<1],val[N],root[N];int L[N],R[N],V[N];int n,len,cnt;bool t[N];char str[10];int lowbit(int x){return x&(-x);}void Insert(int l,int r,int &now,int val,int delta){if(!now)now=++cnt;a[now].sum+=delta;if(l==r)return ;int mid=l+r>>1;if(val<=mid)Insert(l,mid,a[now].l,val,delta);elseInsert(mid+1,r,a[now].r,val,delta);}void update(int x,int val,int delta){while(x<=n){Insert(1,len,root[x],val,delta);x+=lowbit(x);}}int query(int l,int r,int k){int temp=0,mid=l+r>>1;if(l==r)return l;for(int i=0;i<nor.size();i++)temp+=a[a[nor[i]].l].sum;for(int i=0;i<nol.size();i++)temp-=a[a[nol[i]].l].sum;if(k<=temp){for(int i=0;i<nor.size();i++)nor[i]=a[nor[i]].l;for(int i=0;i<nol.size();i++)nol[i]=a[nol[i]].l;return query(l,mid,k);}else{for(int i=0;i<nor.size();i++)nor[i]=a[nor[i]].r;for(int i=0;i<nol.size();i++)nol[i]=a[nol[i]].r;return query(mid+1,r,k-temp);}}int main(){int m,i,j,k,x,l,r;scanf("%d%d",&n,&m);for(i=1;i<=n;i++){scanf("%d",val+i);dis[i]=val[i];}for(i=1,k=0;i<=m;i++){scanf("%s",str);if(str[0]=='Q')scanf("%d%d%d",L+i,R+i,V+i);else{t[i]=1;scanf("%d%d",L+i,V+i);dis[n+(++k)]=V[i];}}sort(dis+1,dis+n+k+1);len=unique(dis+1,dis+n+k+1)-dis-1;for(i=1;i<=n;i++){x=lower_bound(dis+1,dis+len+1,val[i])-dis;update(i,x,1);}for(i=1;i<=m;i++){if(t[i]){x=lower_bound(dis+1,dis+len+1,val[L[i]])-dis;update(L[i],x,-1);x=lower_bound(dis+1,dis+len+1,V[i])-dis;update(L[i],x,1);val[L[i]]=V[i];}else{nol.clear(),nor.clear();for(x=R[i];x;x-=lowbit(x))nor.push_back(root[x]);for(x=L[i]-1;x;x-=lowbit(x))nol.push_back(root[x]);printf("%d\n",dis[query(1,len,V[i])]);}}return 0;}




0 0