树状数组找第k大
倒着来,取了的排名就去掉。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,s[410000]; int lowbit(int x){return x&-x;} void change(int x,int k) { while(x<=405000) { s[x]+=k; x+=lowbit(x); } } int Bin[30]; int findk(int k) { int pos=0,sum=0; for(int i=22;i>=0;i--) if(pos+Bin[i]<=n&&sum+s[pos+Bin[i]]<k) sum+=s[pos+Bin[i]], pos+=Bin[i]; pos++; return pos; } int pos[210000],id[210000],as[210000]; int main() { Bin[0]=1;for(int i=1;i<=25;i++)Bin[i]=Bin[i-1]*2; while(scanf("%d",&n)!=EOF) { memset(s,0,sizeof(s)); for(int i=1;i<=n;i++) scanf("%d%d",&pos[i],&id[i]), pos[i]++, change(i,1); for(int i=n;i>=1;i--) { int k=findk(pos[i]); as[k]=id[i], change(k,-1); } for(int i=1;i<=n;i++)printf("%d ",as[i]); printf(" "); } return 0; }