hdu 2665 划分树

来源:互联网 发布:mysql和oracle的关系 编辑:程序博客网 时间:2024/05/18 01:15

开始用线段树+归并排序,4700+ms飘过~,后来去学划分树,虽然还不是很懂,不过就这样吧

#include<iostream>#include<algorithm>#define maxn 100010using namespace std;int n,m;int nsort[maxn];int nleft[30][maxn],tree[30][maxn];void build(int l,int r,int c){if(l==r) return;int mid=(l+r)/2;int sum=mid-l+1;for(int i=l;i<=r;i++){if(tree[c][i]<nsort[mid]) sum--;}int ll=l,rr=mid+1;for(int i=l;i<=r;i++){if(tree[c][i]<nsort[mid]) tree[c+1][ll++]=tree[c][i];else if(tree[c][i]==nsort[mid]&&sum>0) tree[c+1][ll++]=tree[c][i],sum--;else tree[c+1][rr++]=tree[c][i];nleft[c][i]=nleft[c][l-1]+ll-l;}build(l,mid,c+1);build(mid+1,r,c+1);}int que(int l,int r,int a,int b,int k,int c){if(a==b) return tree[c][a];int mid=(l+r)/2;int cnt=nleft[c][b]-nleft[c][a-1];if(cnt>=k){int nl=l+nleft[c][a-1]-nleft[c][l-1];int nr=nl+cnt-1;return que(l,mid,nl,nr,k,c+1);}else {int nr=b+nleft[c][r]-nleft[c][b];        int nl=nr-(b-a-cnt);        return que(mid+1,r,nl,nr,k-cnt,c+1);}}int main(){cin.sync_with_stdio(false);int t;cin>>t;while(t--){cin>>n>>m;for(int i=1;i<=n;i++){cin>>tree[0][i];nsort[i]=tree[0][i];}sort(nsort+1,nsort+n+1);build(1,n,0);//l,r,层; while(m--){int a,b,k;cin>>a>>b>>k;cout<<que(1,n,a,b,k,0)<<endl;}}return 0;} 


0 0
原创粉丝点击