• Poj 2104(主席树入门


    题目:静态查询区间第k大.

    主席树入门题目,之前看的很多资料一上来就是动态区间第k大,看得很费劲,后来找了个写得清晰的,感觉静态的还不算难,代码也不长.

    /*
    * @author:  Cwind
    */
    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <functional>
    #include <set>
    #include <cmath>
    using namespace std;
    #define IOS std::ios::sync_with_stdio (false);std::cin.tie(0)
    #define pb push_back
    #define PB pop_back
    #define bk back()
    #define fs first
    #define se second
    #define sq(x) (x)*(x)
    #define eps (1e-6)
    #define IINF (1<<29)
    #define LINF (1ll<<59)
    #define INF (1000000000)
    #define FINF (1e3)
    #define clr(x) memset((x),0,sizeof (x));
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    typedef pair<ll,ll> P;
    
    const int maxn=3e6;
    const int maxlen=1e5+300;
    struct Node{
        int ls,rs,v;
        Node():ls(0),rs(0),v(0){}
    }T[maxn];
    int sz=0;
    int d[maxlen],a[maxlen];
    void insert(int &n,int l,int r,int x){
        T[++sz]=T[n];n=sz;
        T[n].v++;
        if(r-l<=1) return;
        int m=(r+l)>>1;
        if(x>=d[m]) insert(T[n].rs,m,r,x);
        else insert(T[n].ls,l,m,x);
    }
    int query(int i,int j,int l,int r,int k){
        if(r-l<=1) return d[l];
        int t=T[T[j].ls].v-T[T[i].ls].v;
        int m=(l+r)>>1;
        if(t>=k) return query(T[i].ls,T[j].ls,l,m,k);
        else return query(T[i].rs,T[j].rs,m,r,k-t);
    }
    int n,m;
    int root[maxlen];
    int main(){
        freopen("/home/files/CppFiles/in","r",stdin);
        cin>>n>>m;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            d[i]=a[i];
        }
        sort(d,d+n);
        for(int i=0;i<n;i++){
            root[i+1]=root[i];
            insert(root[i+1],0,n,a[i]);
        }
           while(m--){
               int x,y,z;
               scanf("%d%d%d",&x,&y,&z);
               printf("%d
    ",query(root[x-1],root[y],0,n,z));
           }
        return 0;
    }
    View Code

    作为入门文章讲的很好:http://www.cnblogs.com/Rlemon/archive/2013/05/23/3094635.html

  • 相关阅读:
    几行代码搞定图片模糊模式
    SVN源代码管理规范
    模仿苹果手机虚拟键的代码分享,有兴趣的可以玩玩。 下面的是链接,复制粘贴到浏览器就能下载
    keytool使用方法
    Unity导出APk出错解决方法二
    学习网址
    eclipse中手动设置library,选择编译工具方法
    apk接入google play邮箱登陆及充值注意事项
    unity导出apk错误出错解决方法
    java自动生成jar包工具
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4854972.html
Copyright © 2020-2023  润新知