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 }