zoukankan      html  css  js  c++  java
  • P4587 [FJOI2016]神秘数 主席树

      现给定n个正整数a[1]..a[n],m个询问,每次询问给定一个区间l,r,求由a[l],a[l+1],…,a[r]所构成的可重复数字集合的神秘数。输出最小的不可由该集合所构成的数

    看到区间很明显是主席树

     

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=2e6+10;
    int T[N],lson[N<<5],rson[N<<5],t[N<<5],n,m,ncnt;
    void upnode(int x,int l,int r,int pre,int &pos)
    {   
        pos=++ncnt;
        t[pos]=t[pre]+x;lson[pos]=lson[pre];rson[pos]=rson[pre];
        if(l==r)return ;int m=(l+r)>>1;
        if(x<=m)upnode(x,l,m,lson[pre],lson[pos]);
        else upnode(x,m+1,r,rson[pre],rson[pos]);
    }
    int qsum(int L,int R,int l,int r,int pre,int pos)
    {
        if(L<=l&&r<=R)return t[pos]-t[pre];
        int m=(l+r)>>1,ans=0;
        if(L<=m)ans+=qsum(L,R,l,m,lson[pre],lson[pos]);
        if(R>m)ans+=qsum(L,R,m+1,r,rson[pre],rson[pos]);
        return ans;
    }
    int main()
    {
        int n;cin>>n;int x,l,r,ans,res,m;
        rep(i,1,n)scanf("%d",&x),upnode(x,1,1e9,T[i-1],T[i]);
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d%d",&l,&r);
            ans=1;
            while(1)
            {
                res=qsum(1,ans,1,1e9,T[l-1],T[r]);
                if(res>=ans)ans=res+1;
                else break;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    osg::BlendFunc来设置透明度
    LCA(Tarjan)
    CODEVS1073 家族 (并查集)
    CODEVS1533 互斥的数(哈希表)
    2014-12-4
    BZOJ2661 连连看 (费用流)
    2014-11-30
    JAVA语法基础作业——动手动脑以及课后实验性问题
    课后作业01——相加
    再读大道至简第二章
  • 原文地址:https://www.cnblogs.com/bxd123/p/11566208.html
Copyright © 2011-2022 走看看