zoukankan      html  css  js  c++  java
  • HDU 4288 Coder ( 离散化 + 离线 + 线段树 )

    这题跟ZOJ 3606的解题思路很相似。

     题意:有3中操作:1.向集合中增加一个数x(1≤x≤1e9);2.从集合中删去一个数x(保证这个数存在);3.查询集合中所有位置满足i%5==3的数a[i]的和,集合中的数按升序排列。给你一共N个操作,输出每次查询的和。

    做法:因为操作只有10^5个,所以将所有查询中的数保存下来,排序之后离散化。每个数对应一个“位置”,通过标记这个“位置”是否已用来表示该数是否在集合中。

    线段树节点记录两个信息:

    cnt:这一段“位置”中含有多少个数,pushUp的时候cnt[rt] = cnt[ rt << 1 ] + cnt[ rt << 1 | 1 ];

    sum[5]:sum[i]表示这个区间中,从左到右编号,位置模5为i的所有数的和。

    pushUp的时候,sum[rt][i] = sum[lc][i], sum[rt][ (i+cnt[lc])%5 ]+= sum[rc][i]

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    
    #define LL long long int
    #define lson l, m, rt << 1
    #define rson m + 1, r, rt << 1 | 1
    #define lc rt << 1
    #define rc rt << 1 | 1
    
    using namespace std;
    
    const int MAXN = 100100;
    
    
    struct Qry
    {
        int op;
        int val;
    } qq[MAXN];
    
    struct node
    {
        LL sum[5];
        int cnt;
    };
    
    int Q;
    int num[MAXN];
    int cnt;
    node Tr[ MAXN << 2 ];
    
    void build( int l, int r, int rt )
    {
        for ( int i = 0; i < 5; ++i ) Tr[rt].sum[i] = 0;
        Tr[rt].cnt = 0;
    
        if ( l == r ) return;
        int m = ( l + r ) >> 1;
        build( lson );
        build( rson );
        return;
    }
    
    void PushUp( int rt )
    {
        Tr[rt].cnt = Tr[lc].cnt + Tr[rc].cnt;
        for ( int i = 0; i < 5; ++i ) Tr[rt].sum[i] = Tr[lc].sum[i];
        for ( int i = 0; i < 5; ++i ) Tr[rt].sum[ (i+Tr[lc].cnt)%5 ] += Tr[rc].sum[i];
        return;
    }
    
    void Update( int x, int op, int l, int r, int rt )
    {
        if ( l == x && x == r )
        {
            for ( int i = 0; i < 5; ++i ) Tr[rt].sum[i] = 0;
            if ( op == 1 )
            {
                Tr[rt].cnt = 1;
                Tr[rt].sum[1] = num[x];
            }
            else if ( op == 2 ) Tr[rt].cnt = 0;
            return;
        }
        int m = ( l + r ) >> 1;
        if ( x <= m ) Update( x, op, lson );
        else Update( x, op, rson );
        PushUp( rt );
        return;
    }
    
    int main()
    {
        while ( scanf( "%d", &Q ) == 1 )
        {
            cnt = 1;
            for ( int i = 0; i < Q; ++i )
            {
                char tmp[8];
                scanf( "%s", tmp );
                if ( tmp[0] == 'a' )
                {
                    qq[i].op = 1;
                    scanf( "%d", &qq[i].val );
                    num[cnt++] = qq[i].val;
                }
                else if ( tmp[0] == 'd' )
                {
                    qq[i].op = 2;
                    scanf( "%d", &qq[i].val );
                    num[cnt++] = qq[i].val;
                }
                else qq[i].op = 3;
            }
    
            sort( num + 1, num + cnt );
            cnt = unique( num + 1, num + cnt ) - num;
            build( 1, cnt - 1, 1 );
    
            for ( int i = 0; i < Q; ++i )
            {
                if ( qq[i].op == 3 )
                    printf( "%I64d
    ", Tr[1].sum[3] );
                else
                {
                    int x = lower_bound( num + 1, num + cnt, qq[i].val ) - num;
                    Update( x, qq[i].op, 1, cnt - 1, 1 );
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    css定位
    题解 P2345 【奶牛集会】
    浅谈主席树
    浅谈Manacher算法
    CSP2019 游记
    P5025 [SNOI2017]炸弹
    浅谈2-SAT
    DAY 5模拟赛
    DAY 3
    Luogu P2915 [USACO08NOV]奶牛混合起来
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3362032.html
Copyright © 2011-2022 走看看