# HDU 3333 Turing Tree 莫队算法

#### 分析：

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

typedef long long LL;

const int maxn = 30000 + 10;
const int maxq = 100000 + 10;

int n, m, a[maxn], b[maxn];
int cnt[maxn];
LL ans[maxq];

struct Query
{
int l, r, id;
bool operator < (const Query& t) const {
return ((l / m) < (t.l / m)) || ((l / m) == (t.l / m) && r < t.r);
}
};

Query q[maxq];

int main()
{
int T; scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) { scanf("%d", a + i); b[i] = a[i]; }
sort(b + 1, b + 1 + n);
int tot = unique(b + 1, b + 1 + n) - b - 1;
for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b;

m = sqrt(n);
int Q; scanf("%d", &Q);
for(int i = 1; i <= Q; i++) {
scanf("%d%d", &q[i].l, &q[i].r);
q[i].id = i;
}
sort(q + 1, q + 1 + Q);

LL sum = 0;
int L = 1, R = 0;
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= Q; i++) {
while(L < q[i].l) {
cnt[a[L]]--;
if(!cnt[a[L]]) sum -= b[a[L]];
L++;
}
while(L > q[i].l) {
L--;
if(!cnt[a[L]]) sum += b[a[L]];
cnt[a[L]]++;
}
while(R < q[i].r) {
R++;
if(!cnt[a[R]]) sum += b[a[R]];
cnt[a[R]]++;
}
while(R > q[i].r) {
cnt[a[R]]--;
if(!cnt[a[R]]) sum -= b[a[R]];
R--;
}
ans[q[i].id] = sum;
}

for(int i = 1; i <= Q; i++) printf("%lld\n", ans[i]);
}

return 0;
}

posted @ 2016-05-09 16:54  AOQNRMGYXLMV  阅读(...)  评论(... 编辑 收藏