【题目大意】
给出一个长度为n的序列和m组查询(i,j,k),输出[i,j]中的第k大数。
【思路】
先离散化然后莫队分块。用树状数组来维护当前每个值的个数,然后对于每次询问二分答案即可。
又一次实力写错二分…(生无可恋脸.jpg)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int MAXN=100000+50; 8 const int MAXM=5000+50; 9 struct node 10 { 11 int l,r,k,pos,id,ans; 12 }q[MAXM]; 13 bool cmp(node x,node y) 14 { 15 return (x.pos==y.pos)?x.r<y.r:x.pos<y.pos; 16 } 17 bool cmpid(node x,node y) 18 { 19 return (x.id<y.id); 20 } 21 struct discretize 22 { 23 int num,pos; 24 bool operator < (const discretize &x) const {return (num<x.num);} 25 }tmp[MAXN]; 26 int n,m; 27 int a[MAXN],e[MAXN]; 28 int ori[MAXN];//离散化后的i对应的原数字为ori[i] 29 30 int lowbit(int x) 31 { 32 return (x&(-x)); 33 } 34 35 void modify(int p,int x) 36 { 37 while (p<=n) 38 { 39 e[p]+=x; 40 p+=lowbit(p); 41 } 42 } 43 44 int sum(int p) 45 { 46 int ret=0; 47 while (p>0) 48 { 49 ret+=e[p]; 50 p-=lowbit(p); 51 } 52 return ret; 53 } 54 55 void init() 56 { 57 scanf("%d%d",&n,&m); 58 for (int i=1;i<=n;i++) 59 { 60 scanf("%d",&tmp[i].num); 61 tmp[i].pos=i; 62 } 63 sort(tmp+1,tmp+n+1); 64 for (int i=1,j=0;i<=n;i++) 65 { 66 if (i==1 || tmp[i].num!=tmp[i-1].num) ++j,ori[j]=tmp[i].num; 67 a[tmp[i].pos]=j; 68 } 69 int block=(int)sqrt(n); 70 for (int i=1;i<=m;i++) 71 { 72 scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k); 73 q[i].id=i; 74 q[i].pos=(q[i].l-1)/block+1; 75 } 76 sort(q+1,q+m+1,cmp); 77 } 78 79 int binary_search(int k) 80 { 81 int lb=0,ub=n; 82 while (ub-lb>1) 83 { 84 int mid=(ub+lb)>>1; 85 if (sum(mid)>=k) ub=mid;else lb=mid;//注意一下二分怎么写 86 } 87 return ub; 88 } 89 90 void solve() 91 { 92 int l=1,r=0; 93 memset(e,0,sizeof(e)); 94 for (int i=1;i<=m;i++) 95 { 96 while (l<q[i].l) modify(a[l],-1),l++; 97 while (l>q[i].l) l--,modify(a[l],1); 98 while (r<q[i].r) r++,modify(a[r],1); 99 while (r>q[i].r) modify(a[r],-1),r--; 100 q[i].ans=binary_search(q[i].k); 101 } 102 sort(q,q+m+1,cmpid); 103 for (int i=1;i<=m;i++) printf("%d ",ori[q[i].ans]); 104 } 105 106 int main() 107 { 108 init(); 109 solve(); 110 return 0; 111 }