• [POJ2104]K-th Number(主席树)


    Description

    给定一个含有N个数的序列(A_1,A_2,A_3……A_n),程序必须回答这样的询问:对于给定的i,j,k,在(A_i,A_{i+1},A_{i+2}...A_j)中第k大的数是多少(1≤k≤j-i+1)。你需要编一个这样的程序,从输入文件中读入序列a,读入一系列的指令,对于每一个指令,你必须输出正确的回答。

    (Nleq 10000)

    Solution

    这是主席树一道入门题目。

    即求区间第K小,考验对于每个数建立一棵可持续化线段树维护,

    区间([l,r])可以转化为(r-l)处理

    Code

    #include <cstdio>
    #include <algorithm>
    #define N 100010
    using namespace std;
    
    int n,m,T[N],ls[N*20],rs[N*20],sum[N*20],tot,rt;
    int num[N],rank[N];
    
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    void update(int last,int p,int l,int r,int &rt){//建树
    	rt=++tot;
    	ls[rt]=ls[last],rs[rt]=rs[last],sum[rt]=sum[last]+1;
    	if(l==r) return;
    	int m=(l+r)>>1;
    	if(p<=m) update(ls[last],p,l,m,ls[rt]);//可持续化
    	else update(rs[last],p,m+1,r,rs[rt]);
    }
    
    int Query(int ss,int tt,int l,int r,int k){
    	if(l==r) return l;
    	int m=(l+r)>>1;
    	int d=sum[ls[tt]]-sum[ls[ss]];
    	if(k<=d) return Query(ls[ss],ls[tt],l,m,k);
    	else return Query(rs[ss],rs[tt],m+1,r,k-d);
    }
    
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;++i){
    		num[i]=read();
    		rank[i]=num[i];
    	}
    	sort(rank+1,rank+n+1);
    	int cnt=unique(rank+1,rank+n+1)-rank-1;//去重
    	for(int i=1;i<=n;++i) num[i]=lower_bound(rank+1,rank+cnt+1,num[i])-rank;//离散化
    	for(int i=1;i<=n;++i) update(T[i-1],num[i],1,cnt,T[i]);//每个数建一棵树
    	while(m--)  {  
        	int l=read(),r=read(),k=read();  
            int p=Query(T[l-1],T[r],1,cnt,k);  
            printf("%d
    ",rank[p]);  
        }  
    	return 0;
    } 
    
  • 相关阅读:
    .gitignore不生效-git上传忽略解决方案的配置文件
    JAVA
    Java
    python-函数基础01
    Java常见数据结构
    分代垃圾回收机制及垃圾回收算法
    设计模式【9】------>观察者模式
    设计模式【8】------>策略模式
    设计模式【7】------>原型模式
    设计模式【6】------>外观模式
  • 原文地址:https://www.cnblogs.com/void-f/p/8385927.html
Copyright © 2020-2023  润新知