zoukankan      html  css  js  c++  java
  • K-th Number Poj

    K-th Number Poj - 2104 主席树

    题意

    给你n数字,然后有m次询问,询问一段区间内的第k小的数。

    解题思路

    这个题是限时训练做的题,我不会,看到这个题我开始是拒绝的,虽然题意清晰简单,但是真的不会。限时结束后,学长说这个题是简单的主席树的入门题,我没学过啊。

    如果你也没有学过的话,建议看我的另一篇博客,上面有自己的总结和一些博客推荐,就不用自己一个一个找了,点我进去

    哦, 这个题是主席树的模板题。

    代码实现

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<algorithm>
    using  namespace std;
    const int maxn=1e5+7;
    int root[maxn], a[maxn], x, y, k;
    int n, m, cnt, tot;
    struct node{
    	int l, r, sum; //左子树的编号,右子树的编号,区间内的标记的数的个数
    }t[maxn*40];
    vector<int> v;
    int getid(int x) //需要进行离散化,因为主席树叶子端点上就是一个数。
    {
    	return lower_bound(v.begin(), v.end(), x) - v.begin() + 1; //这里用vector进行的离散化,比较简单
    }
    void update(int l, int r, int &x, int y, int pos) //注意参数中的l和r是区间范围,和node里面的l和r不一样,node里面的l和r表示左右子树的编号
    //这里相当于建树+更新了,有的博客还单独写了一个build函数,然后再进行update,都行。
    {
    	t[++cnt]=t[y];
    	t[cnt].sum++;
    	x=cnt;//这里是把新节点的编号记录下来
    	if(l==r) return ;
    	int mid=(l+r)>>1;
    	if(pos<=mid)//如果需要添加的编号小于mid,就向左子树走
    		update(l, mid, t[x].l, t[y].l, pos);
    	else //否则就是往右子树走
    		update(mid+1, r, t[x].r, t[y].r, pos);
    }
    int query(int l, int r, int x, int y, int k) //这里的l和r也是区间范围,x是前一个线段树
    {
    	if(l==r)
    		return l;
    	int mid=(l+r)>>1;
    	int sum=t[t[y].l].sum - t[t[x].l].sum; 
    	if(k<=sum)
    		return query(l, mid, t[x].l, t[y].l, k);
    	else 
    		return query(mid+1, r, t[x].r, t[y].r, k-sum);
    }
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(int i=1; i<=n; i++)
    	{
    		scanf("%d", &a[i]);
    		v.push_back(a[i]);
    	}
    	sort(v.begin(), v.end()); //先排序,才能去重+离散化
    	v.erase( unique( v.begin(), v.end() ) , v.end() );//去重
        tot=v.size(); //注意这里很重要,1到tot是我们主席树端点的个数。
    	for(int i=1; i<=n; i++)
    	{
    		update(1, tot, root[i], root[i-1], getid(a[i]) );
    	}
    	for(int i=1; i<=m; i++)
    	{
    		scanf("%d%d%d", &x, &y, &k);
    		printf("%d
    ", v[ query(1, tot, root[x-1], root[y], k) - 1]);
    	}
    	return 0;
     } 
    
    欢迎评论交流!
  • 相关阅读:
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    Live2D 看板娘
    1236:区间合并
  • 原文地址:https://www.cnblogs.com/alking1001/p/11422955.html
Copyright © 2011-2022 走看看