zoukankan      html  css  js  c++  java
  • poj 2104 K-th Number(主席树 视频)

    K-th Number

    题意:

    给你一些数,让你求一个区间内,第k大的数是多少。

    题解:

    主席树第一题,看的qsc视频写的,戳戳戳
    学到了unique函数,他的作用是:把相邻的重复的放到后面,返回值是放后面的第一个的迭代器。 故使用之前要排序,之后在用erase删除后面重复的,便可达到去重的目的,之后就可以离散化了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn=1e5+6;
    int n,m,cnt,root[maxn],a[maxn],x,y,k;
    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;}
    void update(int l,int r,int &x,int y,int pos)
    {
        T[++cnt]=T[y],T[cnt].sum++,x=cnt;
        if (l==r) return;
        int mid=(l+r)/2;
        if (mid>=pos)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)
    {
        if (l==r) return l;
        int mid=(l+r)/2;
        int sum=T[T[y].l].sum-T[T[x].l].sum;
        if (sum>=k)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());
        for(int i=1;i<=n;i++)update(1,n,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,n,root[x-1],root[y],k)-1]);
        }
    }
    

    另一种写法:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=100001;
    struct Node{
        int ls,rs;
        int cnt;
    }tr[maxn*20];
    int cur,rt[maxn];
    void init(){
        cur=0;
    }
    inline void push_up(int o){
        tr[o].cnt=tr[tr[o].ls].cnt+tr[tr[o].rs].cnt;
    }
    int build(int l,int r){
        int k=cur++;
        if (l==r) {
            tr[k].cnt=0;
            return k;
        }
        int mid=(l+r)>>1;
        tr[k].ls=build(l,mid);
        tr[k].rs=build(mid+1,r);
        push_up(k);
        return k;
    }
    int update(int o,int l,int r,int pos,int val){
        int k=cur++;
        tr[k]=tr[o];
        if (l==pos&&r==pos){
            tr[k].cnt+=val;
            return k;
        }
        int mid=(l+r)>>1;
        if (pos<=mid) tr[k].ls=update(tr[o].ls,l,mid,pos,val);
        else tr[k].rs=update(tr[o].rs,mid+1,r,pos,val);
        push_up(k);
        return k;
    }
    int query(int l,int r,int o,int v,int kth){
        if (l==r) return l;
        int mid=(l+r)>>1;
        int res=tr[tr[v].ls].cnt-tr[tr[o].ls].cnt;
        if (kth<=res) return query(l,mid,tr[o].ls,tr[v].ls,kth);
        else return query(mid+1,r,tr[o].rs,tr[v].rs,kth-res);
    }
    int b[maxn];
    int sortb[maxn];
    int main()
    {
        int n,m;
        int T;
        while (~scanf("%d%d",&n,&m)){
            init();
            for (int i=1;i<=n;i++){
                scanf("%d",&b[i]);
                sortb[i]=b[i];
            }
            sort(sortb+1,sortb+1+n);
            int cnt=1;
            for (int i=2;i<=n;i++){
                if (sortb[i]!=sortb[cnt]){
                    sortb[++cnt]=sortb[i];
                }
            }
            rt[0]=build(1,cnt);
            for (int i=1;i<=n;i++){
                int p=lower_bound(sortb+1,sortb+cnt+1,b[i])-sortb;
                rt[i]=update(rt[i-1],1,cnt,p,1);
            }
            for (int i=0;i<m;i++){
                int a,b,k;
                scanf("%d%d%d",&a,&b,&k);
                int idx=query(1,cnt,rt[a-1],rt[b],k);
                printf("%d
    ",sortb[idx]);
            }
        }
        return 0;
    }
  • 相关阅读:
    百度之星初赛 A
    百度之星 初赛 BC
    2016 百度之星资格赛
    codeforces 749
    codeforces 785
    HDU 4617
    网络流 poj 2195
    网络流 poj 3436 poj 3281
    codeforces 780 C
    idea激活
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5716769.html
Copyright © 2011-2022 走看看