zoukankan      html  css  js  c++  java
  • JZOJ 1011. 【GDKOI2009模拟3】Zoo(主席树)

    JZOJ 1011. 【GDKOI2009模拟3】Zoo

    题目

    Description

    JZ拥有一个很大的野生动物园。这个动物园坐落在一个狭长的山谷内,这个区域从南到北被划分成N个区域,每个区域都饲养着一头狮子。这些狮子从北到南编号为1,2,3,…,N。每头狮子都有一个觅食能力值Ai,Ai越小觅食能力越强。饲养员西西决定对狮子进行M次投喂,每次投喂都选择一个区间[I,J],从中选取觅食能力值第K强的狮子进行投喂。值得注意的是,西西不愿意对某些区域进行过多的投喂,他认为这样有悖公平。因此西西的投喂区间是互不包含的(即区间[1,10]不会与[3,4]或[5,10]同时存在,但可以与[9,11]或[10,20]一起)。同一区间也只会出现一次。你的任务就是算出每次投喂后,食物被哪头狮子吃掉了。

    Input

    第一行两个整数N,M。
    第二行N个整数为每只狮子的觅食能力值。(1<=能力值<=maxlongint)。
    此后M行,每行描述一次投喂。第t+2的三个数I,J,K表示在第t次投喂中,西西选择了区间[I,J]内觅食能力值第K强的狮子进行投喂。

    Sample Input

    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1

    Output

    输出文件有M行,每行一个整数。第i行的整数表示在第i次投喂中吃到食物的狮子的觅食能力值。

    Sample Output

    3
    2

    Data Constraint

    对于100%的数据,有1<=N<=100000,1<=M<=50000。

    题解

    这道题是十分裸的主席树,只要懂得主席树的基本操作都会实现。
    【主席树】可持久化线段树
    注意觅食能力值过大,需要给它们进行离散化。

    标程

    #include<cstdio> 
    #include<cstring>
    using namespace std;
    int rt[100010],pr[100010],num=0;
    struct
    {
    	int l,r,sum;
    }f[3000010];
    struct
    {
    	int id,s;
    }a[100010];
    void qsort(int l,int r)
    {
    	int x=l,y=r,mid=a[(l+r)/2].s;
    	while(x<=y)
    	{
    		while(a[x].s<mid) x++;
    		while(a[y].s>mid) y--;
    		if(x<=y) a[0]=a[x],a[x]=a[y],a[y]=a[0],x++,y--;
    	}
    	if(x<r) qsort(x,r);
    	if(y>l) qsort(l,y);
    }
    void make(int v,int l,int r)
    {
    	if(l==r) 
    	{
    		f[v].sum=0;
    		if(v>num) num=v;
    		return;
    	}
    	else
    	{
    		int mid=(l+r)/2;
    		f[v].l=v*2,f[v].r=v*2+1;
    		make(v*2,l,mid);
    		make(v*2+1,mid+1,r);
    	}
    }
    void add(int v,int v1,int l,int r,int x)
    {
    	if(l==r)
    	{
    		f[v1].sum++;
    		return;
    	}
    	else
    	{
    		int mid=(l+r)/2;
    		if(x<=mid)
    		{
    			f[v1].l=++num;
    			f[v1].r=f[v].r;
    			add(f[v].l,f[v1].l,l,mid,x);
    		}
    		else 
    		{
    			f[v1].l=f[v].l;
    			f[v1].r=++num;
    			add(f[v].r,f[v1].r,mid+1,r,x);
    		}
    		f[v1].sum=f[f[v1].l].sum+f[f[v1].r].sum;
    	}
    }
    int find(int v,int v1,int l,int r,int k)
    {
    	if(l==r) return a[l].s;
    	else 
    	{
    		int mid=(l+r)/2,s1=f[f[v1].l].sum-f[f[v].l].sum,s2=f[f[v1].r].sum-f[f[v].r].sum;
    		if(s1>=k) return find(f[v].l,f[v1].l,l,mid,k);
    		else return find(f[v].r,f[v1].r,mid+1,r,k-s1);
    	}
    }
    int main()
    {
    	int n,m,i,l,r,k,q;
    	scanf("%d%d",&n,&q);
    	for(i=1;i<=n;i++) scanf("%d",&a[i].s),a[i].id=i;
    	qsort(1,n);
    	for(i=1;i<=n;i++) pr[a[i].id]=i;
    	rt[0]=1;
    	make(1,1,n);
    	for(i=1;i<=n;i++)
    	{
    		rt[i]=++num;
    		add(rt[i-1],rt[i],1,n,pr[i]);
    	}
    	for(i=1;i<=q;i++)
    	{	
    		scanf("%d%d%d",&l,&r,&k);
    		printf("%d\n",find(rt[l-1],rt[r],1,n,k));
    	}
    	return 0;
    }
    
    哈哈哈哈哈哈哈哈哈哈
  • 相关阅读:
    简单bb两句
    P2894 [USACO08FEB]Hotel G
    文艺平衡树
    CS184.1X 计算机图形学导论作业1
    C++ Primer Plus章节编程练习(第五章)
    C++ Primer Plus章节编程练习(第六章)
    CS184.1X 计算机图形学导论作业0
    C++ Primer Plus章节编程练习(第四章)
    计算机图形学之光栅图形学算法
    Codeforces 980B
  • 原文地址:https://www.cnblogs.com/LZA119/p/13910120.html
Copyright © 2011-2022 走看看