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 }
树状数组加速:
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 }

浙公网安备 33010602011771号