2018-04-04
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1175
一个长度为N的整数序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,第K大的数是多少。
例如: 1 7 6 3 1。i = 1, j = 3,k = 2,对应的数为7 6 3,第2大的数为6。
Input
第1行:1个数N,表示序列的长度。(2 <= N <= 50000) 第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i] <= 10^9) 第N + 2行:1个数Q,表示查询的数量。(2 <= Q <= 50000) 第N + 3 - N + Q + 2行:每行3个数,对应查询的起始编号i和结束编号j,以及k。(0 <= i <= j <= N - 1,1 <= k <= j - i + 1)
Output
共Q行,对应每一个查询区间中第K大的数。
Input示例
5 1 7 6 3 1 3 0 1 1 1 3 2 3 4 2
Output示例
7 6 1
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cctype> using namespace std; inline int gi(){int d=0;char c=getchar();while(!isdigit(c))c=getchar(); while(isdigit(c)){d=(d<<3)+(d<<1)+c-‘0‘;c=getchar();}return d;} const int N=50005; const int M=2000005; struct QUE{ int l,r,i,k; }q[M]; bool cmp1(QUE aa,QUE bb){ return aa.r<bb.r; } int sm[M<<2],ls[M],rs[M],rt[M],tot; int a[N],san[N],num[N],ans[N],cnt; int n,Q; #define gem int mi=(l+r)>>1 void gai(int old,int &o,int l,int r,int P,int C){ o=++tot; ls[o]=ls[old];rs[o]=rs[old];sm[o]=sm[old]+C; if(l==r)return; gem; if(P<=mi)gai(ls[o],ls[o],l,mi,P,C); else gai(rs[o],rs[o],mi+1,r,P,C);//?? } int qur(int old,int o,int l,int r,int k){ if(l==r)return l; int sum=sm[rs[o]]-sm[rs[old]]; gem; if(sum<k)return qur(ls[old],ls[o],l,mi,k-sum); else return qur(rs[old],rs[o],mi+1,r,k); } #define rep(xx,yy,zz) for(xx=yy;xx<=zz;++xx) int main(){ register int i,j; n=gi(); rep(i,1,n){ a[i]=gi();san[i]=a[i]; } sort(san+1,san+n+1); rep(i,1,n) if(i==1||san[i]!=san[i-1]) num[++cnt]=san[i]; Q=gi(); rep(i,1,Q){ q[i].i=i;q[i].l=gi()+1;q[i].r=gi()+1;q[i].k=gi(); } sort(q+1,q+Q+1,cmp1); j=1; rep(i,1,n){ int x=lower_bound(num+1,num+cnt+1,a[i])-num; gai(rt[i-1],rt[i],1,cnt,x,1); for(;q[j].r==i;++j){ ans[q[j].i]=qur(rt[q[j].l-1],rt[i],1,cnt,q[j].k); } } rep(i,1,Q){ printf("%d\n",num[ans[i]]); } return 0; }