題意:求給定去接內不重複數位和
做法: 圖靈樹還是沒有學到....
只要先記錄每個詢問,然後按照右邊界排序,還需要記錄每個位置之前距離它最近那個與他相等的元素的位置。再樹狀數組做一下。
#include <cstdio>#include <cstring>#include <algorithm>#define lowbit(x) ((x)&-(x))typedef __int64 LL;const int LMT = 30003;using namespace std;struct __line{ int l, r, pos; bool operator < (const __line &y)const { return r < y.r; }}line[100003];struct __copy{ int num, pos; bool operator < (const __copy &y)const { if(num != y.num) return num < y.num; return pos < y.pos; }}a_copy[LMT];int a[LMT], n, vis[LMT];LL sum[LMT], ans[100002];void update(int op, int x){ while(x <= n) { sum[x] += op; x += lowbit(x); }}LL query(int x){ LL res = 0; while(x > 0) { res += sum[x]; x -= lowbit(x); } return res;}int main(void){ int q, i, j, T; scanf("%d", &T); while(T--) { memset(vis, -1, sizeof(vis)); memset(sum, 0, sizeof(sum)); scanf("%d", &n); for(i = 1; i <= n; ++i) { scanf("%d", &a[i]); a_copy[i].num = a[i]; a_copy[i].pos = i; } scanf("%d", &q); for(i = 0; i < q; ++i) { scanf("%d%d", &line[i].l, &line[i].r); line[i].pos = i; } sort(line, line + q); sort(&a_copy[1], &a_copy[1] + n); for( i = 2; i <= n; ++i) if (a_copy[i].num == a_copy[i - 1].num) vis[a_copy[i].pos] = a_copy[i - 1].pos; for(i = 1, j = 0; i <= n && j < q; ++i) { update(a[i], i); if (vis[i] != -1) update(-a[i], vis[i]); while(j < q && line[j].r == i) { ans[line[j].pos] = query(line[j].r) - query(line[j].l - 1); ++j; } } for(i = 0; i < q; ++i)printf("%I64d\n", ans[i]); } return 0;}