HDU 3874 Necklace (数状数组)

题意:求[l, r]区间内不重复的数的和。N个数,M次询问

解:离线处理M次询问,看得别人的思路后才知道的。。。思维局限在预处理N个数上了。。。

对M次询问按右区间的值从小到大排序。扫一遍N个数,如果发现当前这个数在之前出现过,就从之前出现这个数的位置上把这个数删除,在新位置上插入这个数。这样做的好处是删除前面重复的不会影响后面的。时间复杂度控制在(N + M)logN的数量级上。

ps:午不眠,困乎,我命休矣。

 

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define Read()  freopen("data.in", "r", stdin)
#define Write() freopen("data.out", "w", stdout);

typedef __int64 LL;
const double eps = 1e-6;
const double PI = acos(-1.0);
const int inf = 0x1F1F1F1F;

using namespace std;

const int N = 50010;
const int M = 200010;

struct node {
    int l, r;
    int id;
    bool operator < (const node& cmp) const {
        return r < cmp.r;
    }
}p[M];

LL c[N];
LL ans[M];
int num[N];
map<int, int> mp;

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

void add(int p, int val) {
    for( ; p < N; p += lowbit(p)) {
        c[p] += val;
    }
}

LL sum(int p) {
    LL res = 0;
    for( ; p > 0; p -= lowbit(p)) {
        res += c[p];
    }
    return res;
}

int main() {
    //Read();

    int T, n, m, i, r, t;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        for(i = 1; i <= n; ++i) scanf("%d", num + i);
        scanf("%d", &m);
        for(i = 0; i < m; ++i) {
            scanf("%d%d", &p[i].l, &p[i].r);
            if(p[i].l > p[i].r) swap(p[i].l, p[i].r);
            p[i].id = i;
        }
        sort(p, p + m);
        memset(c, 0, sizeof(c));
        mp.clear();
        r = 1;
        for(i = 0; i < m; ++i) {
            while(r <= p[i].r) {
                t = num[r];
                if(mp[t] != 0) {
                    add(mp[t], -t);
                }
                add(r, t);
                mp[t] = r++;
            }
            ans[p[i].id] = sum(p[i].r) - sum(p[i].l - 1);
        }
        for(i = 0; i < m; ++i) {
            OUT(ans[i]);
        }
    }
    return 0;
}
View Code

 

 

 

 

 

 

 

posted @ 2013-06-05 13:58  AC_Von  阅读(274)  评论(0编辑  收藏  举报