PAT1057

题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1057

普通算法会超时,用树状数组+二分逼近查找第K小即可

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<stack>
  4 using namespace std;
  5 
  6 int a[100005];
  7 
  8 int lowbit(int t)
  9 {
 10     return t&(t^(t-1));
 11 }
 12 
 13 void add(int pos, int i)
 14 {
 15     while(pos <= 100004)
 16     {
 17         a[pos]+=i;
 18         pos += lowbit(pos);
 19     }
 20 }
 21 
 22 int sum(int pos)
 23 {
 24     int sum(0);
 25     while(pos > 0)
 26     {
 27         sum+=a[pos];
 28         pos -= lowbit(pos);
 29     }
 30     return sum;
 31 }
 32 
 33 int findk(int k)
 34 {
 35     int low(1), high(100004), median;
 36     while(low < high)
 37     {
 38         median=(low+high)/2;
 39         if(sum(median) < k)
 40             low=median+1;
 41         else
 42             high=median;
 43     }
 44     return low;
 45 }
 46 
 47 int str2num(char *choice)
 48 {
 49     int len=strlen(choice);
 50     int radix(1), sum(0);
 51     while(choice[len-1] != ' ')
 52     {
 53         sum += (choice[len-1]-'0')*radix;
 54         radix *= 10;
 55         --len;
 56     }
 57     return sum;
 58 }
 59 
 60 int main()
 61 {
 62     int N;
 63     char choice[50];
 64     scanf("%d",&N);
 65     gets(choice);
 66     stack<int> s;
 67     memset(a, 0, sizeof(a));
 68     for(int i=0; i<N; ++i)
 69     {
 70         gets(choice);
 71         if(strcmp(choice,"Pop") == 0)
 72         {
 73             if(s.empty())
 74                 printf("Invalid\n");
 75             else
 76             {
 77                 printf("%d\n", s.top());
 78                 add(s.top(), -1);
 79                 s.pop();
 80             }
 81         }
 82         else if(strcmp(choice, "PeekMedian") == 0)
 83         {
 84             if(s.empty())
 85                 printf("Invalid\n");
 86             else
 87             {
 88                 int mid;
 89                 if(s.size()%2 == 0)
 90                     mid = s.size()/2;
 91                 else
 92                     mid = s.size()/2 +1;
 93                 printf("%d\n", findk(mid));
 94             }
 95         }
 96         else
 97         {
 98             int num = str2num(choice);
 99             add(num, 1);
100             s.push(num);
101         }
102     }
103     return 0;
104 }

 

posted @ 2013-10-30 18:42  coding_monkey  阅读(227)  评论(0编辑  收藏  举报