在线求第k大,第一次用二分+树状数组写。。。比赛的时候分治啊,splay啊,主席树啊换来换去,然而以前为什么不知道可以这么写。。。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <vector> 7 #include <set> 8 #define inf 1000000007 9 #define maxn 100002 10 11 using namespace std; 12 13 int n; 14 int seq[maxn]; 15 16 struct peo 17 { 18 int h,x; 19 friend bool operator <(peo a, peo b) 20 { 21 return a.h<b.h; 22 } 23 }a[maxn]; 24 25 struct bit 26 { 27 int b[maxn]; 28 int num; 29 void add(int x,int z) 30 { 31 for (int i=x;i<=num;i+=(i&-i)) b[i]+=z; 32 } 33 int ask(int x) 34 { 35 int tmp=0; 36 for (int i=x;i;i-=(i&-i)) tmp+=b[i]; 37 return tmp; 38 } 39 void init(int n) 40 { 41 num=n; 42 memset(b,0,sizeof(b)); 43 } 44 }s; 45 46 int main() 47 { 48 int Case; 49 scanf("%d",&Case); 50 for (int o=1;o<=Case;o++) 51 { 52 int flag=1; 53 scanf("%d",&n); 54 for (int i=1;i<=n;i++) 55 scanf("%d%d",&a[i].h,&a[i].x); 56 sort(a+1,a+n+1); 57 s.init(n); 58 for (int i=1;i<=n;i++) s.add(i,1); 59 60 for (int i=1;i<=n;i++) 61 { 62 int tmp=inf, k=a[i].x; 63 if (1<=k+1 && k+1<=n-i+1) tmp=min(tmp,k+1); 64 if (1<=n-i-k+1 && n-i-k+1<=n-i+1) tmp=min(tmp,n-i-k+1); 65 if (tmp==inf) 66 { 67 flag=0; 68 break; 69 } 70 int l=1,r=n, now; 71 while (l<=r) 72 { 73 int mid=(l+r)>>1; 74 if (s.ask(mid)>=tmp) 75 { 76 now=mid; 77 r=mid-1; 78 } 79 else 80 l=mid+1; 81 } 82 seq[now]=a[i].h; 83 s.add(now,-1); 84 } 85 printf("Case #%d: ",o); 86 if (!flag) printf("impossible\n"); 87 else 88 for (int i=1;i<=n;i++) 89 if (i<n) printf("%d ",seq[i]); 90 else printf("%d\n",seq[i]); 91 } 92 return 0; 93 }