zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Tomcat自定义classLoader加密解密
    阿里巴巴2015秋季校园招聘研发工程师在线笔试题
    【Machine Learning】Mahout基于协同过滤(CF)的用户推荐
    基于Jenkins自动构建系统开发
    反射invoke()方法
    java对象序列化与反序列化
    从文本文件逐行读入数据
    Linux下MySQL小尝试
    【Html 学习笔记】第四节——框架
    穷举法
  • 原文地址:https://www.cnblogs.com/Cw-trip/p/4854972.html
Copyright © 2011-2022 走看看