Hdu--3333(树状数组 or 线段树,离散化,离线)

2014-10-04 15:06:38

思路:这题乍一看不怎么会,后来看题解才知道要离线处理。知道了这个之后自己瞎搞暴力了一通,竟然过了- -!后来用树状数组加速了下。

  大概思路就是,把所有询问读进来,按照询问的右端点升序排序,然后从左到右依次扫所有值(离散后),都加入树状数组,如果发现该值在之前已经出现,那么将之前的值删除后再加入现在这个值,目的就是使得所有数唯一,且尽量靠右。

瞎搞版本:

 1 /*************************************************************************
 2     > File Name: 3333.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Sat 04 Oct 2014 01:35:35 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <queue>
16 #include <iostream>
17 #include <algorithm>
18 using namespace std;
19 #define lp (p << 1)
20 #define rp (p << 1|1)
21 #define getmid(l,r) (l + (r - l) / 2)
22 #define MP(a,b) make_pair(a,b)
23 typedef long long ll;
24 const int INF = 1 << 30;
25 const int maxn = 30010;
26 
27 int T,N,Q;
28 int vis[maxn];
29 ll tsum[maxn],A[maxn],B[maxn];
30 
31 struct Query{
32     int l,r,id;
33     ll sum;
34 }q[100010];
35 
36 bool cmp1(Query a,Query b){
37     return a.r < b.r;
38 }
39 
40 bool cmp2(Query a,Query b){
41     return a.id < b.id;
42 }
43 
44 void Debug(int sz){
45     printf("A[] :");
46     for(int i = 1; i <= N; ++i){
47         printf("%d ",A[i]);
48     }
49     puts("");
50     printf("B[] :");
51     for(int i = 1; i <= sz; ++i)
52         printf("%d ",B[i]);
53     puts("");
54 }
55 
56 int main(){
57     int a,b;
58     scanf("%d",&T);
59     while(T--){
60         scanf("%d",&N);
61         for(int i = 1; i <= N; ++i){
62             scanf("%I64d",&A[i]);
63             B[i] = A[i];
64         }
65         sort(B + 1,B + N + 1);
66         int sz = unique(B + 1,B + N + 1) - B - 1;
67         for(int i = 1; i <= N; ++i)
68             A[i] = lower_bound(B + 1,B + sz + 1,A[i]) - B;
69         //Debug(sz);
70         scanf("%d",&Q);
71         for(int i = 1; i <= Q; ++i){
72             scanf("%d%d",&q[i].l,&q[i].r);
73             q[i].id = i;
74         }
75         sort(q + 1,q + Q + 1,cmp1);
76         tsum[0] = 0;
77         int pos = 1;
78         memset(vis,0,sizeof(vis));
79         for(int i = 1; i <= Q; ++i){
80             for(; pos <= q[i].r; ++pos){
81                 tsum[pos] = tsum[pos - 1];
82                 if(!vis[A[pos]]){
83                     tsum[pos] += B[A[pos]];
84                     vis[A[pos]] = pos;
85                 }
86                 else{
87                     for(int j = vis[A[pos]]; j < pos; ++j)
88                         tsum[j] -= B[A[pos]];
89                     vis[A[pos]] = pos;
90                 }
91             }
92             q[i].sum = tsum[q[i].r] - tsum[q[i].l - 1];
93         }
94         sort(q + 1,q + Q + 1,cmp2);
95         for(int i = 1; i <= Q; ++i)
96             printf("%I64d\n",q[i].sum);
97     }
98     return 0;
99 }
View Code

树状数组加速:

 1 /*************************************************************************
 2     > File Name: 3333.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Sat 04 Oct 2014 01:35:35 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <queue>
16 #include <iostream>
17 #include <algorithm>
18 using namespace std;
19 #define lp (p << 1)
20 #define rp (p << 1|1)
21 #define getmid(l,r) (l + (r - l) / 2)
22 #define MP(a,b) make_pair(a,b)
23 typedef long long ll;
24 const int INF = 1 << 30;
25 const int maxn = 30010;
26 
27 int T,N,Q;
28 int vis[maxn];
29 ll c[maxn];
30 ll A[maxn],B[maxn];
31 
32 struct Query{
33     int l,r,id;
34 }q[100010];
35 ll ans[100010];
36 
37 bool cmp1(Query a,Query b){ return a.r < b.r;}
38 bool cmp2(Query a,Query b){    return a.id < b.id;}
39 
40 int Lowbit(int x){return x & (-x);}
41 void Update(int x,int d){while(x <= N){c[x] += d; x += Lowbit(x);}}
42 ll Getsum(int x){ll res = 0;while(x){res += c[x]; x -= Lowbit(x);}return res;}
43 
44 int main(){
45     int a,b;
46     scanf("%d",&T);
47     while(T--){
48         scanf("%d",&N);
49         memset(c,0,sizeof(c));
50         for(int i = 1; i <= N; ++i){
51             scanf("%I64d",&A[i]);
52             B[i] = A[i];
53         }
54         sort(B + 1,B + N + 1);
55         int sz = unique(B + 1,B + N + 1) - B - 1;
56         for(int i = 1; i <= N; ++i)
57             A[i] = lower_bound(B + 1,B + sz + 1,A[i]) - B;
58         scanf("%d",&Q);
59         for(int i = 1; i <= Q; ++i){
60             scanf("%d%d",&q[i].l,&q[i].r);
61             q[i].id = i;
62         }
63         sort(q + 1,q + Q + 1,cmp1);
64         memset(vis,0,sizeof(vis));
65         int i = 1;
66         for(int k = 1; k <= Q; ++k){
67             for(; i <= q[k].r; ++i){
68                 Update(i,B[A[i]]);
69                 if(vis[A[i]]) Update(vis[A[i]],-B[A[i]]);
70                 vis[A[i]] = i;
71             }
72             ans[q[k].id] = Getsum(q[k].r) - Getsum(q[k].l - 1);
73         }
74         for(int i = 1; i <= Q; ++i)
75             printf("%I64d\n",ans[i]);
76     }
77     return 0;
78 }

 

posted @ 2014-10-04 15:11  Naturain  阅读(189)  评论(0)    收藏  举报