zoj2112 Dynamic Rankings 单点修改区间第k小
来源:互联网 发布:阿里大数据应用案例 编辑:程序博客网 时间:2024/05/21 17:54
题目:给你N个数,M个操作,操作分两种,(Q,L,R,K)询问区间[L,R]第K小的数,(C,L,R)把第L个数改为R。N<=50000,M<=10000
思路:主席树满足前缀和,因此可以用树状数组来维护。直接在原树上进行修改操作的空间复杂度是nlognlogn,会MLE。给树状数组单独开一棵主席树的空间复杂度是mlognlogn。因此要单独开一主席树,两者的和就是结果。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define PI acos(-1.0)#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f// 0x3f3f3f3fconst int maxn=6e4+50;const int maxm=2500010;int arr[maxn];//原数组int num[maxn],siz;//num离散化之后的数组int root[maxn],lson[maxm],rson[maxm],cnt[maxm];//根节点,左儿子,右儿子,区间内的数出现次数的前缀和int tot;int S[maxn];//树状数组的根节点int luse[maxn],ruse[maxn],llen,rlen;//查询时使用的树状数组的根节点void init(){ tot=1; root[0]=lson[0]=rson[0]=cnt[0]=0;//建一棵空树 sort(num+1,num+siz+1);//离散化 siz=unique(num+1,num+siz+1)-num-1;}int Hash(int x){ return lower_bound(num+1,num+siz+1,x)-num;}int update(int rt,int pos,int val){ int newrt=tot++,temp=newrt; cnt[newrt]=cnt[rt]+val; int l=1,r=siz; while(l<r){ int mid=(l+r)/2; if(pos<=mid){ r=mid; lson[newrt]=tot++;rson[newrt]=rson[rt]; newrt=lson[newrt];rt=lson[rt]; } else{ l=mid+1; lson[newrt]=lson[rt];rson[newrt]=tot++; newrt=rson[newrt];rt=rson[rt]; } cnt[newrt]=cnt[rt]+val; } return temp;}int lowbit(int i){ return i&(-i);}int n;void add(int i,int pos,int val){ while(i<=n){ S[i]=update(S[i],pos,val); i+=lowbit(i); }}int query(int left_rt,int right_rt,int k){ int l=1,r=siz; while(l<r){ int mid=(l+r)/2; int lsum=0,rsum=0; for(int i=1;i<=llen;i++) lsum+=cnt[lson[luse[i]]]; for(int i=1;i<=rlen;i++) rsum+=cnt[lson[ruse[i]]]; int temp=rsum-lsum+cnt[lson[right_rt]]-cnt[lson[left_rt]]; if(temp>=k){ r=mid; for(int i=1;i<=llen;i++) luse[i]=lson[luse[i]]; for(int i=1;i<=rlen;i++) ruse[i]=lson[ruse[i]]; left_rt=lson[left_rt]; right_rt=lson[right_rt]; } else{ l=mid+1; k-=temp; for(int i=1;i<=llen;i++) luse[i]=rson[luse[i]]; for(int i=1;i<=rlen;i++) ruse[i]=rson[ruse[i]]; left_rt=rson[left_rt]; right_rt=rson[right_rt]; } } return l;}struct Node{ int kind,L,R,K;}ask[10010];int main(){ int T,N,M; char str[10]; scanf("%d",&T); while(T--){ siz=0; scanf("%d%d",&N,&M); n=N; for(int i=1;i<=N;i++){ scanf("%d",&arr[i]); num[++siz]=arr[i]; } for(int i=1;i<=M;i++){ scanf("%s",str); if(str[0]=='Q'){//查询操作 ask[i].kind=0; scanf("%d%d%d",&ask[i].L,&ask[i].R,&ask[i].K); } else{//修改操作 ask[i].kind=1; scanf("%d%d",&ask[i].L,&ask[i].R); num[++siz]=ask[i].R; } } init(); for(int i=1;i<=n;i++) root[i]=update(root[i-1],Hash(arr[i]),1); for(int i=1;i<=n;i++) S[i]=root[0]; for(int i=1;i<=M;i++){ if(ask[i].kind==0){ llen=rlen=0; for(int j=ask[i].L-1;j>0;j-=lowbit(j)) luse[++llen]=S[j]; for(int j=ask[i].R;j>0;j-=lowbit(j)) ruse[++rlen]=S[j]; int ans=query(root[ask[i].L-1],root[ask[i].R],ask[i].K); printf("%d\n",num[ans]); } else{ add(ask[i].L,Hash(arr[ask[i].L]),-1); arr[ask[i].L]=ask[i].R; add(ask[i].L,Hash(arr[ask[i].L]),1); } } } return 0;}
阅读全文
0 0
- zoj2112 Dynamic Rankings 单点修改区间第k小
- zoj2112(单点修改区间第K小)
- ZOJ 2112 Dynamic Rankings (主席树+单点修改,询问区间第K值)
- ZOJ2112单点修改,区间求第K大
- ZOJ 2112 Dynamic Rankings 树状数组套主席树 单点修改求动态区间第K大
- ZOJ 2112 & BZOJ 1901 Dynamic Rankings(主席树 单点更新 区间第K大)
- BZOJ 1901(Zju2112 Dynamic Rankings-区间第k大(修改,在线)-函数式线段树)
- bzoj 1901: Zju2112 Dynamic Rankings(带修改的区间第k大,树状数组+主席树)
- 1901: Zju2112 Dynamic Rankings 【带修改的区间第k小数】
- zoj 2112 Dynamic Rankings 带修改区间第k大的几种解法
- 【主席树】 ZOJ 2112 Dynamic Rankings 区间第k小值
- ZOJ2112-Dynamic Rankings
- zoj2112 Dynamic Rankings
- ZOJ 2112 Dynamic Rankings 动态区间第k大 分块
- ZOJ2112(区间动态求第K大)
- ZOJ 2112 Dynamic Rankings (动态区间第K大) (线段树套SBT+二分)
- ZOJ 2112 Dynamic Rankings(动态求区间第k大+整体二分)
- ZOJ 1112 Dynamic Rankings【动态区间第K大,整体二分】
- smartUpload 上传时 java.lang.NullPointerException: charsetName异常
- Oracle之序列
- OceanBase:新一代面向金融的分布式关系数据库
- 重映射函数remap的使用,以图像在x和y方向的翻转为例!
- 手写matlab的Kruskal最小生成树(注释很详细)
- zoj2112 Dynamic Rankings 单点修改区间第k小
- 最全Pycharm教程(1)——定制外观
- Android 开源框架之 Android-async-http 源码解读
- HDU 5698 瞬间移动【组合数+逆元】
- OceanBase:新一代面向金融的分布式关系数据库
- 【代码笔记】iOS-NSSearchPathForDirectoriesInDomainsDemo
- 线程安全和不变性
- 更改mysql端口
- 最全Pycharm教程(2)——代码风格