zoukankan      html  css  js  c++  java
  • poj 2104 K-th Number(可持久化线段树)/hdu 2665

    build: 这份代码有以下问题,在离散化得时候并没有按照离散化之后的vector大小进行查找(好像以修正)

    -------------------------------------------------

    题意:想学主席树,你就肯定知道这道题,去买个面包就有10个人会做的区间第k大(你懂得)

    思路:主席树,听说好像其他的也可以做

    下面大概说一下主席树,主席树可以进行离线的区间第k大,好像在线的是用树状数组套主席树(不对请大牛们留言指出),对于主席树的建树,很少有博客描述主席树的建树(可能我看的太少了),大家都是说一些,前缀和操作,很少说这个线段树到底维护的是什么东西,后来看了一篇博客的图(传送门 http://www.cnblogs.com/Empress/p/4652449.html),我才发现,是类似于权值线段树的,现在窝只是对于主席树有一点了解,其他的内容等待二更。

    然后附上我抄袭的主席树代码:(话说里面的去重操作真的帅,村里人没见过)

    之前代码有误,二更---

    三更---修改为从0开始的主席树

    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <math.h>
    #include <vector>
    #include <string>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <algorithm>
    #define zero(a) fabs(a)<eps
    #define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
    #define min( x, y )  ( ((x) < (y)) ? (x) : (y) )
    #define lowbit(x) (x&(-x))
    #define debug(a) cerr<<#a<<"=="<<a<<endl
    typedef long long LL;
    const double pi=acos(-1.0);
    const double eps=1e-8;
    const int inf=0x3f3f3f3f;
    const LL linf=0x3f3f3f3f3f3f3f3f;
    using namespace std;
    
    
    const int maxn=100000+7;
    int n,m,a[maxn],root[maxn],cnt,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();
    }
    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)>>1;
        if(pos<=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)
    {
        if(l==r)return l;
        int mid=(l+r)>>1;
        int now=T[T[y].l].sum-T[T[x].l].sum;
        if(k<=now)query(l,mid,T[x].l,T[y].l,k);
        else query(mid+1,r,T[x].r,T[y].r,k-now);
    }
    
    int main()
    {
        memset(root,0,sizeof(root));
        cnt=0;
        v.clear();
        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(0,v.size()-1,root[i],root[i-1],getid(a[i]));
        }
        while(m--){
            scanf("%d%d%d",&x,&y,&k);
    //        printf("test %d
    ",query(0,v.size()-1,root[x-1],root[y],k));
            printf("%d
    ",v[query(0,v.size()-1,root[x-1],root[y],k)]);
        }
        return 0;
    }
  • 相关阅读:
    视图
    触发器
    DNS
    DHCP
    SSH 详解
    apt-get
    java split
    数组指针 指针数组
    函数指针
    网络协议
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/8625256.html
Copyright © 2011-2022 走看看