1. 程式人生 > >樹狀數組+二分答案查詢第k大的數 (團體程序設計天梯賽 L3-002. 堆棧)

樹狀數組+二分答案查詢第k大的數 (團體程序設計天梯賽 L3-002. 堆棧)

continue IT for == lse mes algorithm tor 設計

前提是數的範圍較小

 1 數據範圍:O(n) 
 2 查第k大的數i:log(n)(樹狀數組查詢小於等於i的數目)*log(n)(二分找到i)
 3 添加:log(n) (樹狀數組)
 4 刪除:log(n) (樹狀數組)

團體程序設計天梯賽 L3-002. 堆棧

 1 /*數據範圍:O(n) 
 2 查第k大的數i:log(n)(樹狀數組查詢小於等於i的數目)*log(n)(二分找到i)
 3 添加:log(n) (樹狀數組)
 4 刪除:log(n) (樹狀數組)
 5 */ 
 6 #include <cstdio>
 7 #include <cstdlib>
 8 #include <cmath>
 9
#include <cstring> 10 #include <set> 11 #include <vector> 12 #include <stack> 13 #include <map> 14 #include <queue> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define maxn 100000 19 20 long a[100005]; 21 long st[100005]; 22 23 int main()
24 { 25 long n,d,l,r,mid,i,g,c=0; 26 char s[20]; 27 for (i=0;i<=maxn;i++) 28 a[i]=0; 29 scanf("%ld",&n); 30 while (n) 31 { 32 n--; 33 scanf("%s",s); 34 if (strcmp(s,"Pop")==0) 35 { 36 if (c==0) 37 { 38 printf("
Invalid\n"); 39 continue; 40 } 41 d=st[c]; 42 printf("%ld\n",d); 43 while (d<=maxn) 44 { 45 a[d]--; 46 d+=(d & (-d)); 47 } 48 c--; 49 } 50 else if (strcmp(s,"Push")==0) 51 { 52 scanf("%ld",&d); 53 c++; 54 st[c]=d; 55 while (d<=maxn) 56 { 57 a[d]++; 58 d+=(d & (-d)); 59 } 60 } 61 else 62 { 63 d=(c+1)>>1; 64 if (c==0) 65 { 66 printf("Invalid\n"); 67 continue; 68 } 69 l=1; r=maxn; 70 while (l<=r) 71 { 72 mid=(l+r)>>1; 73 g=0; 74 i=mid; 75 while (i>=1) 76 { 77 g+=a[i]; 78 i-=(i & (-i)); 79 } 80 if (g>=d) 81 r=mid-1; 82 else 83 l=mid+1; 84 } 85 printf("%ld\n",l); 86 } 87 } 88 return 0; 89 }

樹狀數組+二分答案查詢第k大的數 (團體程序設計天梯賽 L3-002. 堆棧)