zoukankan      html  css  js  c++  java
  • B

    题目链接:https://cn.vjudge.net/contest/284294#problem/B

    题目大意:查询区间内有多少个不相同的数。

    具体思路:主席树的做法,主席树的基础做法是查询区间第k大或者第k小的,但是这个地方查询的是区间内不同的数的个数,我们就按照下标建立主席树,对于区间[l,r],我们存储的是区间[l,r]中有多少个不同的数,对于当前的数,如果没有出现过,我们就在第i个位置给他加上,如果已经出现过,我们在建立下一棵主席树的时候,先将之前的这个数的下标对应的值减去1.探后再在第i个位置加上这个1,这样的话,可以实现题目中的操作了。

    AC代码:

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    # define ll long long
    const int maxn = 1e5+10;
    struct node
    {
        int sum;
        int l,r;
    } tree[maxn*80];
    int sto[maxn],root[maxn];
    vector<int>q;
    int tot;
    void init()
    {
        tot=0;
        root[0]=0;
    }
    int get_id(int t)
    {
        return lower_bound(q.begin(),q.end(),t)-q.begin()+1;
    }
    int add(int pre)
    {
        int t=++tot;
        tree[t].sum=tree[pre].sum+1;
        tree[t].l=tree[pre].l;
        tree[t].r=tree[pre].r;
        return t;
    }
    void update(int &o,int pre,int l,int r,int pos)
    {
        o=add(pre);
        if(l==r)return ;
        int m=(l+r)>>1;
        if(pos<=m)update(tree[o].l,tree[o].l,l,m,pos);
        else update(tree[o].r,tree[o].r,m+1,r,pos);
    }
    int query(int st,int ed,int l,int r,int k){
    if(l==r)return r;
    int sum=tree[tree[ed].l].sum-tree[tree[st].l].sum;
    int m=(l+r)>>1;
    if(k<=sum)return query(tree[st].l,tree[ed].l,l,m,k);
    else return query(tree[st].r,tree[ed].r,m+1,r,k-sum);
    }
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            init();
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&sto[i]);
                q.push_back(sto[i]);
            }
            sort(q.begin(),q.end());
            q.erase(unique(q.begin(),q.end()),q.end());
            int num=q.size();
            for(int i=1; i<=n; i++)
            {
                update(root[i],root[i-1],1,num,get_id(sto[i]));
            }
            int t1,t2,k;
            while(m--){
            scanf("%d %d %d",&t1,&t2,&k);
            printf("%d
    ",q[query(root[t1-1],root[t2],1,num,k)-1]);
            }
        }
        return 0;
    }
  • 相关阅读:
    《C#多线程编程实战》2.7 CountDownEvent
    《C#多线程编程实战》2.6 ManualResetEventSlim
    《C#多线程编程实战》2.5 AutoResetEvent
    《C#多线程编程实战》2.4 SemaphoreSlim
    ConcurrentDictionary与Dictionary 替换
    vs2017 代码格式化 文档排版 编辑 设置文档的格式
    面试笔记
    way.js
    SQL Server 2008 技巧快捷键
    CentOS下Docker与.netcore(四)之 三剑客之一Docker-machine+jenkins简单自动化部署
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10427450.html
Copyright © 2011-2022 走看看