hdu 3874 树状数组

思路:和求区间内有多少个不同的数一样,只不过改下权值。

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

#include<cstring>

#define Maxn 50010

#define LL __int64

#define lowbit(x) (x&(-x))

using namespace std;

int pre[1000010],num[Maxn],n;

LL ans[Maxn*4],C[Maxn];

struct Query{

    int i,l,r;

    int operator<(const Query &temp) const{

        return r<temp.r;

    }

}qt[Maxn*4];

void update(int pos,LL val)

{

    while(pos<=n){

        C[pos]+=val;

        pos+=lowbit(pos);

    }

}

LL Sum(int pos)

{

    LL sum=0;

    while(pos){

        sum+=C[pos];

        pos-=lowbit(pos);

    }

    return sum;

}

int main()

{

    int i,j,t,m;

    scanf("%d",&t);

    while(t--){

        memset(C,0,sizeof(C));

        memset(pre,0,sizeof(pre));

        scanf("%d",&n);

        for(i=1;i<=n;i++)

            scanf("%d",&num[i]);

        scanf("%d",&m);

        for(i=1;i<=m;i++){

            scanf("%d%d",&qt[i].l,&qt[i].r);

            qt[i].i=i;

        }

        sort(qt+1,qt+1+m);

        int j=1;

        for(i=1;i<=n;i++){

            int pos=pre[num[i]];

            update(pos+1,num[i]);

            update(i+1,-num[i]);

            pre[num[i]]=i;

            while(qt[j].r==i&&j<=m){

                ans[qt[j].i]=Sum(qt[j].l);

                j++;

            }

            if(j>m) break;

        }

        /*

        for(i=1;i<=n;i++)

            printf("%I64d\n",Sum(i));

        */

        for(i=1;i<=m;i++)

            printf("%I64d\n",ans[i]);

    }

    return 0;

}

 

你可能感兴趣的:(树状数组)