zoukankan      html  css  js  c++  java
  • HDU 4747 Mex ( 线段树好题 + 思路 )

    参考:http://www.cnblogs.com/oyking/p/3323306.html

    相当不错的思路,膜拜之~

    个人理解改日补充。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define lc rt << 1
    #define rc rt << 1 | 1
    #define LL long long int
    
    using namespace std;
    
    const int MAXN = 200010;
    
    struct node
    {
        int pos;
        int next;
    };
    
    LL sum[ MAXN << 2 ];
    int maxi[ MAXN << 2 ];
    int mini[ MAXN << 2 ];
    int N;
    int num[MAXN];
    node D[ MAXN << 1 ];
    int head[MAXN];
    int EdgeN;
    
    void AddEdge( int u, int v )
    {
        D[EdgeN].pos = v;
        D[EdgeN].next = head[u];
        head[u] = EdgeN++;
        return;
    }
    
    void PushDown( int rt, int m )
    {
        if ( maxi[rt] == mini[rt] )
        {
            maxi[lc] = mini[lc] = maxi[rt];
            sum[lc] = (LL)maxi[rt]*( m - ( m >> 1 ) );
            maxi[rc] = mini[rc] = mini[rt];
            sum[rc] = (LL)maxi[rt]*( m >> 1 );
        }
        return;
    }
    
    void PushUp( int rt )
    {
        sum[rt] = sum[lc] + sum[rc];
        maxi[rt] = max( maxi[lc], maxi[rc] );
        mini[rt] = min( mini[lc], mini[rc] );
        return;
    }
    
    void build( int l, int r, int rt )
    {
        if ( l == r )
        {
            sum[rt] = maxi[rt] = mini[rt] = N - l + 1;
            return;
        }
        int m = ( l + r ) >> 1;
        build( lson );
        build( rson );
        PushUp( rt );
        return;
    }
    
    void update( int L, int R, int val, int l, int r, int rt )
    {
        if ( L <= l && r <= R && mini[rt] >= val )
        {
            sum[rt] = (LL)val*(r - l + 1);
            maxi[rt] = mini[rt] = val;
            return;
        }
        if ( l == r ) return;
        PushDown( rt, r - l + 1 );
        int m = ( l + r ) >> 1;
        if ( L <= m && maxi[lc] > val ) update( L, R, val, lson );
        if ( R > m && maxi[rc] > val )  update( L, R, val, rson );
        PushUp( rt );
        return;
    }
    
    int main()
    {
        while ( scanf( "%d", &N ) == 1 && N )
        {
            for ( int i = 1; i <= N; ++i )
                scanf( "%d", &num[i] );
            memset( head, -1, sizeof(int)*(N+2) );
            EdgeN = 1;
            for ( int i = N; i > 0; --i )
            {
                if ( num[i] <= N )
                    AddEdge( num[i], i );
            }
            build( 1, N, 1 );
            LL ans = 0;
            for ( int i = 0; i <= N && sum[1]; ++i )
            {
                int pre = 0;
                for ( int j = head[i]; j != -1; j = D[j].next )
                {
                    update( pre + 1, D[j].pos, N - D[j].pos + 1, 1, N, 1 );
                    pre = D[j].pos;
                    //printf("num=%d pos=%d
    ", i, D[j].pos );
                }
                update( pre + 1, N, 0, 1, N, 1 );
                ans += sum[1];
                //printf( "ans=%I64d
    ", ans );
            }
            printf("%I64d
    ", ans );
        }
        return 0;
    }
  • 相关阅读:
    javascript如何封装函数
    addEventListener和attachEvent区别
    Infinity NaN undefined和null
    hasOwnProperty
    蜂巢式图片墙布局
    复选框使用总结
    文本框获得焦点时改变背景颜色
    自定义动画animate
    click()、bind()、live()和delegate()方法
    图片提示效果
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3325221.html
Copyright © 2011-2022 走看看