标签:
题意:给定一个区间,q个查询,对于每次查询回答这个区间内所有不重复的数的和。
思路:可以考虑使用树状数组来做。
先读入所有查询,离线来做,将所有查询按右端点升序排序。
那么我们从给定区间的第一个元素开始遍历这个区间,在此过程中更新每一个元素上一次出现的位置,每次将现在位置加上a[i]并将lastpos位置减去a[i],
也就是说,我们每一步都是保留与当前位置距离最近的重复元素值,其余置零,那么这样肯定能保证答案正确,
如果遍历到的这个位置恰好是一个询问的右端点,那么我们输出修改后的区间值之和。
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #define eps 1e-6 #define LL long long #define pii (pair<int, int>) //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int maxn = 30000 + 300; const int maxq = 100000+1000; //const int INF = 0x3f3f3f3f; int n, q; int a[maxn], lastpos[maxn]; LL C[maxn]; map<int, int> Hash; int ha; struct Query { int l, r, id; bool operator < (const Query& A) const { return r < A.r; } } query[maxq]; LL ans[maxq]; int lowbit(int x) { return (x&(-x)); } LL sumv(int x) { LL ret = 0; while(x > 0) { ret += C[x]; x -= lowbit(x); } return ret; } void add(int x, int d) { while(x <= n) { C[x] += d; x += lowbit(x); } } int dis(int x) { if(!Hash.count(x)) return Hash[x] = ++ha; return Hash[x]; } void init() { ha = 0; Hash.clear(); memset(lastpos, 0, sizeof(lastpos)); memset(C, 0, sizeof(C)); } int main() { // freopen("input.txt", "r", stdin); int T; cin >> T; while(T--) { init(); cin >> n; for(int i = 1; i <= n; i++) scanf("%d", &a[i]); cin >> q; for(int i = 0; i < q; i++) { int u, v; scanf("%d%d", &u, &v); query[i].l = u; query[i].r = v; query[i].id = i; } sort(query, query+q); int cnt = 0; for(int i = 1; i <= n; i++) { if(!lastpos[dis(a[i])]) add(i, a[i]), lastpos[dis(a[i])] = i; else { add(i, a[i]); add(lastpos[dis(a[i])], -a[i]); lastpos[dis(a[i])] = i; } while(cnt<q && query[cnt].r == i) { ans[query[cnt].id] = sumv(query[cnt].r)-sumv(query[cnt].l-1); cnt++; } } for(int i = 0; i < q; i++) printf("%I64d\n", ans[i]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 3333 Turing Tree(树状数组 || 线段树)
标签:
原文地址:http://blog.csdn.net/u014664226/article/details/47307779