hdu3333 Turing Tree

题目大意:求一个区间内不重复数字的和,例如1 1 1 3,区间[1,4]的和为4。


思路:如果采用在线算法,很难在nlogn的时间内处理,所以考虑离线算法。

首先我们把所有查询区间记录下来,然后按照区间的右值排序,接着从左到右把每一个数更新到线段树中,并记录它出现的位置。

如果一个数已经出现过,那么我们就把他上次出现的位置的值置为0,并更新它出现的位置。

因为我们的查询区间是按右值排序的,所以当前区间的左值要么和之前一样要么比之前的要大,因此把过去重复出现的数字置为0不会影响结果。

当更新到某个区间的右值时,我们就查询一次该区间的答案,并把答案记录到对应的地方。

最后把区间查询的答案按照输入顺序输出即可。

View Code
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <set>
 6 #include <vector>
 7 #include <queue>
 8 #include <stack>
 9 #include <cmath>
10 #include <map>
11 using namespace std;
12 #define INF 0x73737373
13 #define EPS 1e-8
14 #define lson l, m, rt<<1
15 #define rson m+1, r, rt<<1|1
16 #define MAXN 55555
17 __int64 sum[MAXN<<2], A[MAXN], ans[MAXN<<2];
18 map <__int64, int> hash;
19 struct Query_Node
20 {
21     int l, r, index;
22     friend bool operator < (Query_Node a, Query_Node b)
23     {
24         return a.r < b.r;
25     }
26 }q[MAXN<<2];
27 void push_up(int rt)
28 {
29     sum[rt] = sum[rt<<1|1] + sum[rt<<1];
30 }
31 void update(int l, int r, int rt, int p, __int64 val)
32 {
33     if(l == r)
34     {
35         sum[rt] += val;
36         return;
37     }
38     int m = (l + r) >> 1;
39     if(p <= m) update(lson, p, val);
40     else update(rson, p, val);
41     push_up(rt);
42 }
43 __int64 query(int l, int r, int rt, int L, int R)
44 {
45     if(L <= l && R >= r)
46         return sum[rt];
47     int m = (l + r) >> 1;
48     __int64 ret = 0;
49     if(L <= m) ret += query(lson, L, R);
50     if(R > m) ret += query(rson, L, R);
51     return ret;
52 }
53 int main()
54 {
55     int t;
56     scanf("%d", &t);
57     while(t--)
58     {
59         int n, m;
60         hash.clear();
61         memset(sum, 0, sizeof(sum));
62         scanf("%d", &n);
63         for(int i = 1; i <= n; i++)
64             scanf("%I64d", &A[i]);
65         scanf("%d", &m);
66         for(int i = 0; i < m; i++)
67         {
68             scanf("%d%d", &q[i].l, &q[i].r);
69             q[i].index = i;
70         }
71         sort(q, q + m);
72         int pos = 1;
73         for(int i = 0; i < m; i++)
74         {
75             for(;pos <= n && pos <= q[i].r; pos++)
76             {
77                 if(hash[A[pos]]) update(1, n, 1, hash[A[pos]], -A[pos]);
78                 update(1, n, 1, pos, A[pos]);
79                 hash[A[pos]] = pos;
80             }
81             ans[q[i].index] = query(1, n, 1, q[i].l, q[i].r);
82         }
83         for(int i = 0; i < m; i++)
84             printf("%I64d\n", ans[i]);
85     }
86     return 0;
87 }
原文地址:https://www.cnblogs.com/deadblue/p/2683199.html