zoukankan      html  css  js  c++  java
  • hdu 2665 划分树

    開始用线段树+归并排序,4700+ms飘过~,后来去学划分树。尽管还不是非常懂,只是就这样吧

    #include<iostream>
    #include<algorithm>
    #define maxn 100010
    using 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;
    } 


  • 相关阅读:
    高斯消元(学习笔记)
    离散化(学习笔记)
    并查集(学习笔记)
    模板---负环(学习笔记)
    差分数组 前缀和(学习笔记)
    manacher马拉车算法(学习笔记)
    Java 常用对象-Object类
    Java 值传递和引用传递
    Java 集合-Set接口和三个子类实现
    Java 集合-Arrays工具类的介绍
  • 原文地址:https://www.cnblogs.com/llguanli/p/8590594.html
Copyright © 2011-2022 走看看