hdu2852(2009多校第四场) 树状数组求区间第k大的数 两种方法
二分查找n*logn*logn
比较容易理解
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define maxx 100005 5 using namespace std; 6 int vis[100010],c[100010],k; 7 int sum(int x) 8 { 9 int ret=0; 10 while (x>0){ 11 ret+=c[x]; 12 x-=(x&-x); 13 } 14 return ret; 15 } 16 void add(int x,int d) 17 { 18 while (x<=maxx){ 19 c[x]+=d; 20 x+=(x&-x); 21 } 22 } 23 int binery(int l,int r) 24 { 25 int mid=l+(r-l)/2,t1,t2,t3; 26 t1=sum(l); t2=sum(mid); t3=sum(r); 27 if (t1==t3) return l; 28 if (t2<k) return binery(mid+1,r); 29 else return binery(l,mid); 30 } 31 int main() 32 { 33 int n,x,y; 34 while (~scanf("%d",&n)) 35 { 36 memset(vis,0,sizeof(vis)); 37 memset(c,0,sizeof(c)); 38 while (n--) 39 { 40 scanf("%d",&x); 41 if (x==0) 42 { 43 scanf("%d",&y); 44 vis[y]++; 45 add(y,1); 46 } 47 else if (x==1) 48 { 49 scanf("%d",&y); 50 if (vis[y]==0){ 51 printf("No Elment!\n"); 52 continue; 53 } 54 vis[y]--; 55 add(y,-1); 56 } 57 else 58 { 59 scanf("%d%d",&y,&k); 60 if (sum(100000)-sum(y)<k){ 61 printf("Not Find!\n"); 62 continue; 63 } 64 k=sum(y)+k; 65 printf("%d\n",binery(1,100000)); 66 } 67 } 68 } 69 return 0; 70 }
利用树状数组自身的特点,和数的二进制拆分关系
神奇优美的nlogn方法
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 #define maxx 100005 5 using namespace std; 6 int vis[100010],c[100010]; 7 int sum(int x) 8 { 9 int ret=0; 10 while (x>0){ 11 ret+=c[x]; 12 x-=(x&-x); 13 } 14 return ret; 15 } 16 void add(int x,int d) 17 { 18 while (x<=maxx){ 19 c[x]+=d; 20 x+=(x&-x); 21 } 22 } 23 int find_kth(int k) 24 { 25 int ans=0,cnt=0,i; 26 for (i=20;i>=0;i--) 27 { 28 ans+=(1<<i); 29 if (ans>=maxx||cnt+c[ans]>=k) 30 ans-=(1<<i); 31 else cnt+=c[ans]; 32 } 33 return ans+1; 34 } 35 int main() 36 { 37 int n,x,y,k; 38 while (~scanf("%d",&n)) 39 { 40 memset(vis,0,sizeof(vis)); 41 memset(c,0,sizeof(c)); 42 while (n--) 43 { 44 scanf("%d",&x); 45 if (x==0) 46 { 47 scanf("%d",&y); 48 vis[y]++; 49 add(y,1); 50 } 51 else if (x==1) 52 { 53 scanf("%d",&y); 54 if (vis[y]==0){ 55 printf("No Elment!\n"); 56 continue; 57 } 58 vis[y]--; 59 add(y,-1); 60 } 61 else 62 { 63 scanf("%d%d",&y,&k); 64 if (sum(100000)-sum(y)<k){ 65 printf("Not Find!\n"); 66 continue; 67 } 68 printf("%d\n",find_kth(sum(y)+k)); 69 } 70 } 71 } 72 return 0; 73 }