P1168 中位数

P1168 中位数
树状数组+二分答案。
树状数组就是起一个高效查询比二分出来的数小的有几个。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<queue>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<ctime>
  7 #include<set>
  8 #include<map>
  9 #include<stack>
 10 #include<cstring>
 11 #define inf 2147483647
 12 #define For(i,a,b) for(register int i=a;i<=b;i++)
 13 #define p(a) putchar(a)
 14 #define g() getchar()
 15 //by war
 16 //2017.11.7
 17 using namespace std;
 18 int a[100010],b[100010],c[100010];
 19 int n;
 20 int t[100010];
 21 int x,l,r,mid;
 22 int now,Min;
 23 void in(int &x)
 24 {
 25     int y=1;
 26     char c=g();x=0;
 27     while(c<'0'||c>'9')
 28     {
 29     if(c=='-')
 30     y=-1;
 31     c=g();
 32     }
 33     while(c<='9'&&c>='0')x=(x<<1)+(x<<3)+c-'0',c=g();
 34     x*=y;
 35 }
 36 
 37 void modify(int k)
 38 {
 39     for(;k<=n;k+=(-k)&k)
 40     t[k]++;
 41 }
 42 
 43 int get(int k)
 44 {
 45     int cnt=0;
 46     for(;k>0;k-=(-k)&k)
 47     cnt+=t[k];
 48     return cnt;
 49 }
 50 
 51 void o(int x)
 52 {
 53     if(x<0)
 54     {
 55         p('-');
 56         x=-x;
 57     }
 58     if(x>9)o(x/10);
 59     p(x%10+'0');
 60 }
 61 int main()
 62 {
 63     in(n);
 64     For(i,1,n)
 65     in(a[i]),b[i]=a[i];
 66     sort(b+1,b+n+1);
 67     int len=unique(b+1,b+n+1)-b-1;
 68     For(i,1,n)
 69     {
 70         x=a[i];
 71         a[i]=lower_bound(b+1,b+len+1,a[i])-b;
 72         c[a[i]]=x;
 73     }
 74     For(i,1,n)
 75     b[i]=0;
 76     o(c[a[1]]),p('
');
 77     b[a[1]]++;
 78     modify(a[1]);
 79     for(int i=3;i<=n;i+=2)
 80       {
 81           b[a[i]]++;
 82           b[a[i-1]]++;
 83           modify(a[i]);
 84           modify(a[i-1]);
 85           l=1,r=n;
 86           while(l<r)
 87           {
 88             mid=(l+r)>>1;
 89             if(b[mid]==0)
 90             {
 91                 now=get(mid);
 92                 if(now*2>i)
 93                 r=mid;
 94                 else
 95                 l=mid+1;
 96           }
 97           else
 98           if(b[mid]==1)
 99           {
100               now=get(mid-1);
101                 if(now*2+1==i)
102                 {
103                     o(c[mid]),p('
');
104                     break;
105             }
106             if(now*2>i)
107                 r=mid;
108                 else
109                 l=mid+1;
110           }
111           else
112           {
113               now=get(mid);
114               Min=get(mid-1);
115               if(now*2>=i&&Min*2<i)
116               {
117                     o(c[mid]),p('
');
118                     break;
119             }
120             if(Min*2>i)
121             r=mid;
122             else
123             l=mid+1;
124           }
125         }
126       }
127      return 0;
128 }
原文地址:https://www.cnblogs.com/war1111/p/7798737.html