hdu-3333-Turing Tree(树状数组)

很好的一道题,感觉很巧妙

题意:求一段区间里,不相同数的和

分析:离线查询,详细见代码;

// File Name: 3333.cpp
// Author: Zlbing
// Created Time: 2013/7/22 21:08:44

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)

const int MAXN=3e4+1000;
LL tree[MAXN];
    int n;
int lowbit(int x)
{
    return x&(-x);
}

void add(int pos,int val)
{
    while(pos<=n)
    {
        tree[pos]+=val;
        pos+=lowbit(pos);
    }
}

LL read(int x)
{
    LL s=0;
    while(x>0)
    {
        s+=tree[x];
        x-=lowbit(x);
    }
    return s;
}

struct seg{
    int l,r;
    int pos;
    bool operator <(const seg& rsh)const{
        return r<rsh.r;
    }
}G[100050];
int A[MAXN];
map<int,int>hash;
LL ans[100050];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        REP(i,1,n)
            scanf("%d",&A[i]);
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&G[i].l,&G[i].r);
            G[i].pos=i;
        }
        sort(G+1,G+m+1);
        hash.clear();
        CL(tree,0);
        int k=1;
        for(int i=1;i<=m;i++)
        {
            for(;k<=G[i].r;k++)
            {
                if(hash[A[k]])    
                {
                    add(hash[A[k]],-A[k]);
                }
                add(k,A[k]);
                hash[A[k]]=k;
            }
            ans[G[i].pos]=read(G[i].r)-read(G[i].l-1);
        }
        for(int i=1;i<=m;i++)
            printf("%I64d\n",ans[i]);
    }
    return 0;
}

 

posted @ 2013-07-22 22:41  z.arbitrary  阅读(224)  评论(0编辑  收藏  举报