zoukankan      html  css  js  c++  java
  • 主席树模板(poj 2104&&poj2761)

    主席树,就是n个线段树,用nlonn的空间实现

    首先建立第一个线段树

    把要查询的值离散化,建立值的线段树

    每一次加入一个点

    显然每一次只会修改logn个点

    把其他的点直接建边连接即可

    代码:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int N=100005;
    int rt[N],a[N],n,m,b[N],x,cnt=1,now,y,k;
    struct Tree
    {
        int num,l,r,ls,rs;
    }T[80*N];
    int ef(int x)
    {
        int l=1,r=cnt;
        while (l<r)
         {
             int mid=(l+r)/2;
             if (b[mid]<x)l=mid+1;
             else r=mid;
         }
        return l; 
    }
    int build(int l,int r)
    {
        now++;
        if (l==r)
         {
              T[now].l=l;
            T[now].r=r;
            return now;
         }
        int k=now;
        T[k].l=l;T[k].r=r;
        int mid=(l+r)/2;
        if (l<=mid)T[k].ls=build(l,mid);
        if (mid<r)T[k].rs=build(mid+1,r);
        return k;
    }
    int insert(int x,int l,int r,int s)
    {
        now++;
        if (l==r)
         {
              T[now].l=l;
            T[now].r=r;
            T[now].num=T[x].num+1;
            return now;
         }
        int k=now,mid=(l+r)/2;
        T[k].l=l;T[k].r=r;
        if (s<=mid)
         {
             T[k].ls=insert(T[x].ls,l,mid,s);
             T[k].rs=T[x].rs;
         }
        else
         {
             T[k].ls=T[x].ls;
             T[k].rs=insert(T[x].rs,mid+1,r,s);
         }
        T[k].num=T[T[k].ls].num+T[T[k].rs].num;
        return k;
    }
    int find(int x,int y,int z)
    {
        if (T[x].l==T[x].r)return T[x].l;
        if (T[T[x].ls].num-T[T[y].ls].num>=z)return find(T[x].ls,T[y].ls,z);
        else return find(T[x].rs,T[y].rs,z-T[T[x].ls].num+T[T[y].ls].num);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)scanf("%d",&a[i]);
        for (int i=1;i<=n;i++)b[i]=a[i];
        sort(b+1,b+n+1);
        for (int i=2;i<=n;i++)
         if (b[i]!=b[i-1])
          b[++cnt]=b[i];
        rt[0]=1;build(1,n);
        for (int i=1;i<=n;i++)rt[i]=now+1,insert(rt[i-1],1,n,ef(a[i]));
        while (m--)
         {
             scanf("%d%d%d",&x,&y,&k);
             swap(x,y);
             printf("%d
    ",b[find(rt[x],rt[y-1],k)]);
         }
        return 0; 
    }
  • 相关阅读:
    Blend操作入门: 别站在门外偷看,快进来吧!
    Egyee,这个世界很美丽
    在Windows Azure中使用自己的域名
    Windows Azure服务购买,收费,使用注意事项及学习资料推荐
    Silverlight怎样加载xap中的各个程序集
    WCF RIA Service随想
    Silverlight布局,也许不止这么多(附照片墙示例及源码)
    An introduction to variable and feature selection
    Compressed Learning
    Robust PCA (摘抄)
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/7900258.html
Copyright © 2011-2022 走看看