• 【主席树】Gym


    主席树里每个值的位置存当前该值出现的最右位置。

    如果root[r]的前缀主席树中,某值最右位置大于等于l,说明该值出现在了l,r中。

    所以主席树维护区间最小值,如果左半值域的最小值<l,则说明左半值域有值未在l,r出现,则查询左子树;否则查询右子树。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 1000010
    struct Node{int v,lc,rc;}T[N*22];
    int root[N],e;
    void Insert(int pre,int cur,int p,int v,int l,int r)
    {
        if(l==r)
          {
            T[cur].v=v;
            return;
          }
        int m=(l+r>>1);
        if(p<=m)
          {
            T[cur].lc=++e;
            T[cur].rc=T[pre].rc;
            Insert(T[pre].lc,T[cur].lc,p,v,l,m);
          }
        else
          {
            T[cur].rc=++e;
            T[cur].lc=T[pre].lc;
            Insert(T[pre].rc,T[cur].rc,p,v,m+1,r);
          }
        T[cur].v=min(T[T[cur].lc].v,T[T[cur].rc].v);
    }
    int Goal;
    int Query(int R,int l,int r)
    {
        if(l==r) return l;
        int m=(l+r>>1);
        if(T[T[R].lc].v<Goal) return Query(T[R].lc,l,m);
        else return Query(T[R].rc,m+1,r);
    }
    int n,m,a[N];
    int main()
    {
        int x,y;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
          {
          	scanf("%d",&x);
            root[i]=++e;
            Insert(root[i-1],root[i],x+1,i,1,1000001);
          }
        scanf("%d",&m);
        for(;m;--m)
          {
            scanf("%d%d",&x,&y);
            Goal=x;
            printf("%d
    ",Query(root[y],1,1000001)-1);
          }
        return 0;
    }
  • 相关阅读:
    MVC5个人用户账户身份验证集成google和facebook的OAuth2登陆
    2016.8.5
    2016.7.29
    2016.7.25
    如何将返回的JSon字符串用MAP格式读取
    代码里获得系统时间写法
    Mybatis中<![cdata[ ]]>
    Orcal语法Merge into用法
    Page.IsPostBack属性
    Android之打开闪光灯关键代码
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7143286.html
Copyright © 2020-2023  润新知