zoukankan      html  css  js  c++  java
  • 主席树入门野生动物园

    有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域
    都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强
    。饲养员cmdButtons决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子
    进行投喂。值得注意的是,cmdButtons不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此cmdButtons
    的投喂区间是互不包含的。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。
    Input
    输入文件第一行有两个数N和M。此后一行有N个数,从南到北描述狮子的觅食能力值。此后M行,每行描述一次投喂
    。第t+2的三个数I,J,K表示在第t次投喂中,cmdButtons选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。
    1<=N<=100000,1<=M<=50000
    Output
    有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。
    Sample Input
    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1
    Sample Output
    3
    2

    #include<bits/stdc++.h>
    #include<algorithm>
    #define N 100010
    using namespace std;
    int sum[N*20],rt[N*20],ch[N*20][2],a[N],b[N],n,m,tot;
    void build(int &now,int l,int r)
    {
    	now=++tot;
    	sum[now]=0;
    	if(l==r)return ;
    	int mid=(l+r)>>1;
    	build(ch[now][0],l,mid);
    	build(ch[now][1],mid+1,r);
    }
    void update(int &now,int l,int r,int last,int p)
    //now结点的编号,l,r左右边界,last上一个树对应结点的编号(根对根,左对左,右对右)
    //p要加入的值 
    {
    	now=++tot;//新开一个结点出来,并复制上一个树的左右结点 
    	ch[now][0]=ch[last][0];
    	ch[now][1]=ch[last][1];
    	sum[now]=sum[last]+1;
    	if(l==r)return ;
    	int mid=(l+r)>>1;
    	if(p<=mid)
    	   update(ch[now][0],l,mid,ch[last][0],p);
    	else 
    	    update(ch[now][1],mid+1,r,ch[last][1],p);
    }
    int query(int l,int r,int x,int y,int k)
    {
    	if(l==r)return l;
    	int mid=(l+r)>>1;
    	int cnt=sum[ch[y][0]]-sum[ch[x][0]];
    	if(k<=cnt)
    	   return query(l,mid,ch[x][0],ch[y][0],k);
    	else 
    	   return query(mid+1,r,ch[x][1],ch[y][1],k-cnt);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]),b[i]=a[i];
    	sort(b+1,b+n+1);
    	int tt=unique(b+1,b+n+1)-b-1;
    	for(int i=1;i<=n;i++)
    	    a[i]=lower_bound(b+1,b+n+1,a[i])-b;
    	build(rt[0],1,tt);
    	for(int i=1;i<=n;i++)
    	     update(rt[i],1,tt,rt[i-1],a[i]);
    //	for (int i=0;i<=n;i++)
    //	cout<<i<<"    "<<rt[i]<<endl;
    	while(m--)
    	{
    		int x,y,k;
    		scanf("%d%d%d",&x,&y,&k);
    		printf("%d
    ",b[query(1,tt,rt[x-1],rt[y],k)]);
    	}
    }
    
    /*
    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1
    
    rt[0]...1
    rt[1]...14
    rt[2]...18
    rt[3]...22
    rt[4]...26
    rt[5]...30
    rt[6]...34
    rt[7]...37
    */ 
    

      

  • 相关阅读:
    Array对象---添加或删除数组中的元素->splice()
    微信小程序-文本作用域
    微信小程序-模块化
    属性动画的核心方法:ValueAnimator.ofInt(int... values)
    关于原生+WebView js交互、数据传输问题
    Beam Search快速理解及代码解析
    vue项目启动报错 spawn cmd ENOENT errno
    TortoiseGit提交每次都需要输入账号密码的解决办法
    Grpc.Core.RpcException: Status(StatusCode=DeadlineExceeded, Detail="Deadline Exceeded")
    公司限制网络,不能访问b站..etc,怎么办?搞起来
  • 原文地址:https://www.cnblogs.com/cutemush/p/11789308.html
Copyright © 2011-2022 走看看