尋找第k大數
阿新 • • 發佈:2018-11-04
#include "stdafx.h" #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int maxn=11000000; typedef long long ll; //分塊陣列做法 const int sqrN=316; int block[sqrN]; int table[maxn]; int findkth(int k){ int sum=0; int idx=0; while(sum+block[idx]<k) sum+=block[idx++]; int num=idx*sqrN; while(sum+table[num]<k) sum+=table[num++]; return num; }
//樹狀陣列做法
int lowbit(int x){ return x&(-x);} int c[maxn]; void update(int x,int v){ for(int i=x;i<maxn;i+=lowbit(i)){ c[i]+=v;} } int getsum(int x){ int sum=0; for(int i=x;i>0;i-=lowbit(i)){ sum+=c[i]; } return sum; } int findKth(int k){ int l=1,r=maxn,mid; while(l<r){ mid=(l+r)/2; if(getsum(mid)>=k)r=mid;//相當於尋找lower_bound()找到第一個大於等於k的數 else l=mid+1; } return l; }
//快速排序演算法 int randpartition(int a[],int l,int r){ int p=1.0*rand()/RAND_MAX*(r-l)+l; swap(a[p],a[l]); int temp=a[l]; while(l<r){ while(l<r&&a[r]>temp)r--; a[l]=a[r]; while(l<r&&a[l]<=temp)l++; a[r]=a[l]; } a[l]=temp;return l; } void randselect(int a[],int l,int r,int k){ int p=randpartition(a,l,r); int m=p-l+1; if(k==m)return; else if(k<m)randselect(a,l,p-1,k); else randselect(a,p+1,r,k-m); } int main(){ freopen("c://jin.txt","r",stdin); memset(block,0,sizeof(block)); memset(table,0,sizeof(table)); int n; cin>>n; int a; while(n--) {cin>>a; block[a/sqrN]++; table[a]++; update(a,1);
} freopen("CON","r",stdin);
system("pause");
return 0;
}