您的位置:首页 > 其它

HDU 3874 Necklace (数状数组)

2013-06-05 13:58 309 查看
题意:求[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
;
LL ans[M];
int num
;
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: