【COGS257】动态排名系统
来源:互联网 发布:德勤财务咨询 知乎 编辑:程序博客网 时间:2024/06/05 01:22
[问题描述]
给定一个长度为N的已知序列Ai,要求维护这个序列,能够支持以下两种操作:
1、查询A[i],A[i+1],A[i+2],…,Aj中,升序排列后排名第k的数。
2、修改A[i]的值为j。
所谓排名第k,指一些数按照升序排列后,第k位的数。例如序列{6,1,9,6,6},排名第3的数是6,排名第5的数是9。
[输入格式]
第一行包含一个整数D(0<=D<=4),表示测试数据的数目。接下来有D组测试数据,每组测试数据中,首先是两个整数N(1<=N<=50000),M(1<=M<=10000),表示序列的长度为N,有M个操作。接下来的N个不大于1,000,000,000正整数,第i个表示序列A[i]的初始值。然后的M行,每行为一个操作
Q i j k 或者
C i j
分别表示查询A[i],A[i+1],A[i+2],…,Aj中,升序排列后排名第k的数,和修改A[i]的值为j。
[输出格式]
对于每个查询,输出一行整数,为查询的结果。测试数据之间不应有空行。
[样例输入]
2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
[样例输出]
3
6
3
6
一开始线段树乱搞,写了个错误性很显然的代码交上去还以为没问题
结果就是这么显然的错误竟然能A5个点2333
后来受了启发做了两个改变就A了.
1.把修改操作在读入时拆分成两个操作,一个是删除,一个是插入(核心就是这个位置.其实线段树乱搞加上这一步也可以A的)
2.把线段树改成了树状数组简洁好看www
我的整体二分也算是写熟了>w<
//AC code by CreationAugust#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MAXN 100010#define MAXINT 0x7fffffff#define lowbit(x) x&-xusing namespace std;int T;int n,m;int ans[MAXN];int a[MAXN],last[MAXN];char ch[2];int c[MAXN];int top=0,num=0,l,r,k;struct Query{ int l,r,x,op,k;}ques[MAXN],q1[MAXN],q2[MAXN];void add(int i,int x){ while (i>0&&i<=num) c[i]+=x,i+=lowbit(i);}int sum(int l,int r){ int ret=0; while (r>0) ret+=c[r],r-=lowbit(r); while (l>0) ret-=c[l],l-=lowbit(l); return ret;}void solve(int L,int R,int l,int r){ int mid=(L+R)>>1,tp1=0,tp2=0; if (l>r) return; if (L==R) { for (int i=l;i<=r;i++) if (ques[i].op==2) ans[ques[i].x]=a[mid]; return; } for (int i=l;i<=r;i++) { if (ques[i].op==1) { if (ques[i].k<=a[mid]) add(ques[i].l,ques[i].r),q1[++tp1]=ques[i]; else q2[++tp2]=ques[i]; } else { int temp=sum(ques[i].l-1,ques[i].r); if (ques[i].k<=temp) q1[++tp1]=ques[i]; else ques[i].k-=temp,q2[++tp2]=ques[i]; } } for (int i=1;i<=tp1;i++) if (q1[i].op==1) add(q1[i].l,-q1[i].r); memcpy(ques+l,q1+1,sizeof(Query)*tp1); memcpy(ques+l+tp1,q2+1,sizeof(Query)*tp2); solve(L,mid,l,l+tp1-1); solve(mid+1,R,l+tp1,r);}int main(){ freopen("dynrank.in","r",stdin); freopen("dynrank.out","w",stdout); scanf("%d",&T); while (T--) { memset(ans,0,sizeof(ans)); Query temp[MAXN]; top=0;num=0; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) { scanf("%d",&a[++top]);last[top]=a[top]; ques[++num]=((Query){i,1,i,1,a[top]}); } for (int i=n+1;i<=n+m;i++) { scanf("%s",ch); if (ch[0]=='Q') { scanf("%d%d%d",&l,&r,&k); ques[++num]=((Query){l,r,num,2,k}); } else { scanf("%d%d",&l,&k);a[++top]=k; ques[++num]=((Query){l,1,num,1,k});//将一个修改操作拆分成一个删除,一个插入 ques[++num]=((Query){l,-1,num,1,last[l]}); last[l]=k; } } sort(a+1,a+top+1); top=unique(a+1,a+top+1)-a-1; for (int i=1;i<=num;i++) temp[i]=ques[i]; solve(1,top,1,num); for (int i=1;i<=num;i++) if (temp[i].op!=1) printf("%d\n",ans[i]); }}
- 【COGS257】动态排名系统
- COGS-257-动态排名系统-树状数组+主席树
- 【COGS】257 动态排名系统 【动态第K小】树状数组+主席树
- Elo排名系统
- GPA排名系统
- ELO Rating排名系统
- [HAOI2008]排名系统
- 4043:GPA排名系统
- [HAOI2008]排名系统
- 排名系统的设计
- 1056: [HAOI2008]排名系统
- 【u242】排名系统
- 【bzoj1056】[HAOI2008]排名系统
- [BZOJ1901]Dynamic Rankings 动态排名
- 【BZOJ】【P1862】【P1056】【排名系统】【GameZ游戏排名系统】
- [HAOI2008] 排名系统 & [ZJOI2006] GameZ游戏排名系统 [SPLAY]【数据结构】
- 1056: [HAOI2008]排名系统/1862: [Zjoi2006]GameZ游戏排名系统
- 推荐系统和搜索排名
- Android 调用WebService 查手机号的应用
- UVA - 10635 Prince and Princess
- 项目三:用多文件组织多个类的程序
- AddTwoNumbers
- Reactor设计模式基础知识
- 【COGS257】动态排名系统
- Convert Sorted Array to Binary Search Tree
- poj 3128 Leonardo's Notebook (置换群)
- CODEVS 3243 区间翻转 (SBT)
- 常见向量范数和矩阵范数
- [XML] SAX解析
- 守护进程的设计与实现
- mvc架构模式与视图控制器
- 基于JZ2440的按键控制GPIO灯的亮灭