题意:求[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; }