zoukankan      html  css  js  c++  java
  • HDU 3874 Necklace 树状数组

     题意:求区间内不同的数的和

    离线处理,按查询右端点从小到大排序,从左往右扫一遍。

    记录每个数出现的上一个位置,如果该数之前没有出现过,就加上,否则就在上一个位置减去。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    
    #define LL long long int
    
    using namespace std;
    
    const int MAXN = 1000100;
    
    struct node
    {
        int id;
        int l, r;
    };
    
    int N, Q;
    int pre[MAXN];      //某数之前出现的位置
    LL sum[50100];
    LL val[50100];
    int maxL;
    node D[200100];
    LL ans[200100];
    
    int lowbit( int x )
    {
        return x&(-x);
    }
    
    LL query( int x )
    {
        LL res = 0;
        while ( x > 0 )
        {
            res += sum[x];
            x -= lowbit(x);
        }
        return res;
    }
    
    void update( int x, int val )
    {
        while ( x <= N )
        {
            sum[x] += val;
            x += lowbit(x);
        }
        return;
    }
    
    bool cmp( node a, node b )
    {
        if ( a.r != b.r ) return a.r < b.r;
        else if ( a.l != b.r ) return a.l < b.l;
        return a.id < b.id;
    }
    
    int main()
    {
        int T;
        scanf( "%d", &T );
        while ( T-- )
        {
            scanf( "%d", &N );
            for ( int i = 1; i <= N; ++i )
                scanf( "%I64d", &val[i] );
    
            scanf( "%d", &Q );
            for ( int i = 0; i < Q; ++i )
            {
                D[i].id = i;
                scanf( "%d%d", &D[i].l, &D[i].r );
            }
    
            memset( pre, -1, sizeof(pre) );
            memset( sum,  0, sizeof(sum) );
    
            sort( D, D + Q, cmp );
    
            int cur = 1;
            for ( int i = 0; i < Q; ++i )
            {
                while ( cur <= D[i].r )
                {
                    if ( pre[ val[cur] ] != -1 )
                        update( pre[ val[cur] ], -val[cur] );
    
                    update( cur, val[cur] );
                    pre[ val[cur] ] = cur;
                    ++cur;
                }
                ans[ D[i].id ] = query( D[i].r ) - query( D[i].l - 1 );
            }
            for ( int i = 0; i < Q; ++i )
                printf( "%I64d
    ", ans[i] );
    
        }
        return 0;
    }
  • 相关阅读:
    Extension:WYSIWYG
    partprobe
    Centos install Parosid
    linux 打造man中文帮助手册图解
    男人到了二十几岁后
    Mediawiki update to 1.24
    华为笔试题
    排序算法
    求素质的算法
    判断有符号和无符号数和符号
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3270868.html
Copyright © 2011-2022 走看看