【COGS257】动态排名系统
2015-04-08 20:03
274 查看
[问题描述]
给定一个长度为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<
给定一个长度为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<
[code]//AC code by CreationAugust #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define MAXN 100010 #define MAXINT 0x7fffffff #define lowbit(x) x&-x using 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 动态排名系统 【动态第K小】树状数组+主席树
- 【BZOJ 1901】Zju2112 Dynamic Rankings &&【COGS 257】动态排名系统 树状数组套线段树
- 【BIT套主席树】COGS257-动态排名系统
- bzoj1901&zoj2112&cogs257 Dynamic Rankings(动态排名系统)
- COGS-257-动态排名系统-树状数组+主席树
- Cogs_动态排名系统[整体二分]
- COGS 197 [HAOI2008] 排名系统
- C#下实现动态系统托盘图标
- 让编辑框动态显示系统时间
- ArcGIS 9在WIN XP 和 WIN 2003 系统下安装部分动态库不能注册的解决办法
- C#显示动态光标和图标动态系统托盘
- C#下实现动态系统托盘图标
- C#下实现动态系统托盘图标
- 在SDI工程的视图中的OnDraw()函数中动态显示系统的时间
- [导入]MSSQL系统表及动态表创建
- autofs服务动态自动挂载各种文件系统
- PB9.0如何动态获取系统时间
- C#下实现动态系统托盘图标
- “动态文章发布系统”开发手记