HDU

先上题目:

Necklace

Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2330    Accepted Submission(s): 831


Problem Description
Mery has a beautiful necklace. The necklace is made up of N magic balls. Each ball has a beautiful value. The balls with the same beautiful value look the same, so if two or more balls have the same beautiful value, we just count it once. We define the beautiful value of some interval [x,y] as F(x,y). F(x,y) is calculated as the sum of the beautiful value from the xth ball to the yth ball and the same value is ONLY COUNTED ONCE. For example, if the necklace is 1 1 1 2 3 1, we have F(1,3)=1, F(2,4)=3, F(2,6)=6.

Now Mery thinks the necklace is too long. She plans to take some continuous part of the necklace to build a new one. She wants to know each of the beautiful value of M continuous parts of the necklace. She will give you M intervals [L,R] (1<=L<=R<=N) and you must tell her F(L,R) of them.
 
Input
The first line is T(T<=10), representing the number of test cases.
  For each case, the first line is a number N,1 <=N <=50000, indicating the number of the magic balls. The second line contains N non-negative integer numbers not greater 1000000, representing the beautiful value of the N balls. The third line has a number M, 1 <=M <=200000, meaning the nunber of the queries. Each of the next M lines contains L and R, the query.
 
Output
For each query, output a line contains an integer number, representing the result of the query.
 
Sample Input
2
6
1 2 3 4 3 5
3
1 2
3 5
2 6
6
1 1 1 2 3 5
3
1 1
2 4
3 5
 
Sample Output
3
7
14
1
3
6
  题意:给出n个数值,给出m个区间,求每个区间不同数值的和。
  这题可以用树状数组来做。
  分析是这样的:首先我们假设询问的区间是按照从左往右的顺序(每一个询问的区间都是按照右边界进行排序,从小到大)询问的。那么我们可以发现:如果当前询问的区间与上一个区间没有交集,那么上次的询问的时候如果对对数据修改的话在这次询问中不会有影响;如果当前区间与上一次询问的区间有交集的话,由于题意说是求一个区间里面不同数值的和。我们可以将在两个区间中都出现的数值,在前方出现过的位置减掉,那么如果我们用树状数组维护的话就可以得出每一个询问的正确答案了。
  具体需要看代码。
 
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 50000
#define NUM 1000000
#define Qu 200000
#define LL __int64
using namespace std;

LL c[MAX+4];
LL s[MAX+4];
LL qu[Qu+4];
int vis[NUM+4];
int n,m;

typedef struct{
    int l,r;
    int id;
}Q;

Q q[Qu+4];

bool cmp(Q x,Q y){
    if(x.r==y.r) return x.l<y.l;
    return x.r<y.r;
}

int lowbit(int a){
    return a&(-a);
}

void add(int r,LL v){
    for(int i=r;i<=n;i+=lowbit(i)){
        s[i]+=v;
    }
}

LL sum(int r){
    LL ans=0;
    for(int i=r;i>0;i-=lowbit(i)){
        ans+=s[i];
    }
    return ans;
}

int main()
{
    int t;
    //freopen("data.txt","r",stdin);
    scanf("%d",&t);
    while(t--){
        memset(c,0,sizeof(c));
        memset(s,0,sizeof(s));
        memset(vis,0,sizeof(vis));
        memset(q,0,sizeof(q));
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%I64d",&c[i]);
        }
        scanf("%d",&m);
        for(int i=0;i<m;i++){
            scanf("%d %d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        sort(q,q+m,cmp);
        int k=1;
        for(int i=0;i<m;i++){
            while(k<=q[i].r){
                if(vis[c[k]]!=0){
                    add(vis[ c[k] ],-c[k]);
                }
                vis[c[k]]=k;
                add(vis[c[k]],c[k]);
                k++;
            }
            qu[q[i].id]=sum(q[i].r)-sum(q[i].l-1);
        }
        for(int i=0;i<m;i++){
            printf("%I64d
",qu[i]);
        }
    }
    return 0;
}
3874
原文地址:https://www.cnblogs.com/sineatos/p/3561323.html