zoukankan      html  css  js  c++  java
  • HDOJ 4747 Mex

     

    非常好的线段树题。。。。此题必定会火。。。。。

    Mex

    Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
    Total Submission(s): 955    Accepted Submission(s): 320


    Problem Description
    Mex is a function on a set of integers, which is universally used for impartial game theorem. For a non-negative integer set S, mex(S) is defined as the least non-negative integer which is not appeared in S. Now our problem is about mex function on a sequence.

    Consider a sequence of non-negative integers {ai}, we define mex(L,R) as the least non-negative integer which is not appeared in the continuous subsequence from aL to aR, inclusive. Now we want to calculate the sum of mex(L,R) for all 1 <= L <= R <= n.
     

    Input
    The input contains at most 20 test cases.
    For each test case, the first line contains one integer n, denoting the length of sequence.
    The next line contains n non-integers separated by space, denoting the sequence.
    (1 <= n <= 200000, 0 <= ai <= 10^9)
    The input ends with n = 0.
     

    Output
    For each test case, output one line containing a integer denoting the answer.
     

    Sample Input
    3
    0 1 3
    5
    1 0 2 0 10
     

    Sample Output
    5
    24
    Hint
    For the first test case:mex(1,1)=1, mex(1,2)=2, mex(1,3)=2, mex(2,2)=0, mex(2,3)=0,mex(3,3)=0. 1 + 2 + 2 + 0 +0 +0 = 5.
     

    Source
     

    Recommend
    liuyiding
     

    图片

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>

    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1

    using namespace std;

    const int maxn=200005;

    typedef long long int LL;

    int a[maxn],mex[maxn],next[maxn],mx[maxn<<2],sig[maxn<<2],cnt;
    LL sum[maxn<<2];
    bool vis[maxn];

    void pushUP(int rt)
    {
        mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }

    void pushDOWN(int rt,int len)
    {
        if(~sig[rt])
        {
            sig[rt<<1]=sig[rt<<1|1]=sig[rt];
            mx[rt<<1]=mx[rt<<1|1]=sig[rt];
            sum[rt<<1]=sig[rt]*(len-len>>1);
            sum[rt<<1|1]=sig[rt]*(len>>1);
            sig[rt]=-1;
        }
    }

    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            mx[rt]=mex[cnt];
            sum[rt]=mex[cnt++];
            return ;
        }
        int m=(r+l)>>1;
        build(lson);
        build(rson);
        pushUP(rt);
    }

    LL query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            return sum[rt];
        }
        pushDOWN(rt,r-l+1);
        int m=(l+r)>>1;
        LL ret=0;
        if(L<=m) ret+=query(L,R,lson);
        if(R>m) ret+=query(L,R,rson);
        return ret;
    }

    int getID(int L,int R,int v,int l,int r,int rt)
    {
        if(l==r)
            return l;
        pushDOWN(rt,r-l+1);
        int m=(r+l)>>1;
        if(L<=m&&mx[rt<<1]>v) return getID(L,R,v,lson);
        else if(R>m&&mx[rt<<1|1]>v) return getID(L,R,v,rson);
        return R+1;
    }

    void update(int L,int R,int c,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            sig[rt]=c;
            mx[rt]=c;
            sum[rt]=c*(r-l+1);
            return ;
        }
        pushDOWN(rt,r-l+1);
        int m=(r+l)>>1;
        if(L<=m) update(L,R,c,lson);
        if(R>m) update(L,R,c,rson);
        pushUP(rt);
    }

    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF&&n)
        {
            for(int i=1;i<=n;i++)
                scanf("%d",a+i);
            memset(vis,false,sizeof(vis));
            mex[1]=0;
            if(a[1]<n) vis[a[1]]=true;
            while(vis[mex[1]]) mex[1]++;
            for(int i=2;i<=n;i++)
            {
                if(a<n) vis[a]=true;
                mex=mex[i-1];
                while(vis[mex]) mex++;
            }
            map<int,int> mII;
            for(int i=n;i>=1;i--)
            {
                if(mII.find(a)==mII.end()) next=n+1;
                else next=mII[a];
                mII[a]=i;
            }
            cnt=1;LL ans=0;
            memset(mx,0,sizeof(mx));
            memset(sum,0,sizeof(sum));
            memset(sig,-1,sizeof(sig));
            build(1,n,1);
            for(int i=1;i<=n;i++)
            {
                ans+=query(i,n,1,n,1);
                int st=getID(i+1,next-1,a,1,n,1);
                int ed=next-1;
                if(st<=ed) update(st,ed,a,1,n,1);
            }
            printf("%I64d ",ans);
        }
        return 0;
    }
    * This source code was highlighted by YcdoiT. ( style: Codeblocks )
  • 相关阅读:
    Js实现页面跳转的几种方式
    android给View设置上下左右边框
    mac下安装tomcat
    Series.str方法
    loc() iloc() at() iat()函数
    sudo: pip:找不到命令
    杀死进程方法
    unique()与nunique()
    object数据类型
    set_index()与reset_index()函数
  • 原文地址:https://www.cnblogs.com/CKboss/p/3350838.html
Copyright © 2011-2022 走看看