HDU 3333 Turing Tree

Turing Tree

http://acm.hdu.edu.cn/showproblem.php?pid=3333

分析:

  这道题目叫 图灵树。

  离线+树状数组。

  维护到每个右端点的答案,直接查询左端点,树状数组维护。一个数字不能出现两次,会发现如果出现了多个数,最右边的数可以代替左边的所有数,所以只加入最右边一个数即可。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<iostream>
 6 #include<cctype>
 7 #include<set>
 8 #include<vector>
 9 #include<queue>
10 #include<map>
11 #define pa pair<int,int>
12 #define mp make_pair
13 #define fi(s) freopen(s,"r",stdin);
14 #define fo(s) freopen(s,"w",stdout);
15 using namespace std;
16 typedef long long LL;
17 
18 inline int read() {
19     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
20     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
21 }
22 
23 const int N = 30005;
24 
25 struct Bit{
26     int n; LL sum[N];
27     void Clear() { memset(sum, 0, sizeof(sum)); }
28     void update(int p,int v) {
29         for (; p<=n; p+=(p&(-p))) sum[p] += v;
30     }
31     LL query(int p) {
32         LL ans = 0;
33         for (; p; p-=(p&(-p))) ans += sum[p];
34         return ans;
35     }
36 }bit;
37 int last[N], disc[N], a[N];
38 LL ans[100005]; // 数据范围! 
39 vector< pa > vec[N];
40 
41 void solve() { 
42     int n = read(), cnt = 1;
43     for (int i=1; i<=n; ++i) 
44         a[i] = read(), disc[i] = a[i];
45     sort(disc + 1, disc + n + 1);
46     for (int i=2; i<=n; ++i) if (disc[i] != disc[cnt]) disc[++cnt] = disc[i];
47     for (int i=1; i<=n; ++i) 
48         a[i] = lower_bound(disc + 1, disc + cnt + 1, a[i]) - disc;
49     int Q = read();
50     for (int i=1; i<=Q; ++i) {
51         int l = read(), r = read();
52         vec[r].push_back(mp(l, i));
53     }
54     bit.n = n;
55     for (int i=1; i<=n; ++i) {
56         if (last[a[i]]) bit.update(last[a[i]], -disc[a[last[a[i]]]]);
57         bit.update(i, disc[a[i]]);
58         last[a[i]] = i;
59         for (int sz=vec[i].size(),j=0; j<sz; ++j) 
60             ans[vec[i][j].second] = bit.query(i) - bit.query(vec[i][j].first - 1);
61     }
62     for (int i=1; i<=Q; ++i) printf("%lld\n",ans[i]);
63     bit.Clear();
64     memset(last, 0, sizeof(last));
65     for (int i=1; i<=n; ++i) vec[i].clear();
66 }
67 
68 int main() {
69     int T = read();
70     while (T--) 
71         solve();
72     return 0;
73 }

 

posted @ 2018-10-09 10:43  MJT12044  阅读(152)  评论(0编辑  收藏  举报