# HDU 3333 | Codeforces 703D 树状数组、离散化

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

 1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 33333;
5 const int maxq = 111111;
6 struct node{
7     int l,r,index;
8 };
9 node query[maxq];
10 ll sum[maxn],ans[maxq];
11 ll a[maxn],b[maxn],last[maxn];
12 int n;
13 bool cmp(node a,node b){
14     return a.r < b.r;
15 }
16 ll getsum(int i){
17     ll s = 0;
18     while(i > 0){
19         s += sum[i];
20         i -= i&(-i);
21     }
22     return s;
23 }
24 void add(int i,ll x){
25     while(i <= n){
26         sum[i] += x;
27         i += i&(-i);
28     }
29 }
30 int main(){
31     int t;
32     scanf("%d",&t);
33     while(t--){
34         scanf("%d",&n);
35         for(int i = 1;i<=n;i++){
36             scanf("%I64d",&a[i]);
37             b[i] = a[i];//离散化用
38         }
39         sort(b+1,b+1+n);//排序，以每个数的下标标记
40         int q;
41         scanf("%d",&q);
42         for(int i = 1;i<=q;i++){
43             scanf("%d%d",&query[i].l,&query[i].r);
44             query[i].index = i;
45         }
46         sort(query+1,query+1+q,cmp);
47         memset(sum,0,sizeof(sum));
48         memset(last,0,sizeof(last));
49         int cnt = 1;//每个查询的下标
50         for(int i = 1;i<=n;i++){
51             int index = lower_bound(b+1,b+1+n,a[i])-b-1;//找到该数对应的下标
52             if(last[index])//判断该数是否出现过，有的话减去
55             last[index] = i;
56             while(query[cnt].r==i && cnt<=q){
57                 ans[query[cnt].index] = getsum(query[cnt].r)-getsum(query[cnt].l-1);
58                 cnt++;
59             }
60         }
61         for(int i = 1;i<=q;i++)
62             printf("%I64d\n",ans[i]);
63     }
64     return 0;
65 } 
View Code

Codeforces 703D:http://codeforces.com/contest/703/problem/D

 1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4
5 const int maxn = 1111111;
6 struct node{
7     int l,r,index;
8 };
9 node query[maxn];
10 ll sum[maxn],a[maxn],b[maxn],c[maxn],last[maxn],ans[maxn];
11 int n;
12 bool cmp(node a,node b){
13     return a.r < b.r;
14 }
15 ll getsum(int i){
16     ll s = 0;
17     while(i > 0){
18         s ^= sum[i];//注意
19         i -= i&(-i);
20     }
21     return s;
22 }
23 void add(int i,ll x){
24     while(i <= n){
25         sum[i] ^= x;//注意
26         i += i&(-i);
27     }
28 }
29 int main(){
30     scanf("%d",&n);
31     for(int i = 1;i<=n;i++){
32         scanf("%I64d",&a[i]);
33         c[i] = a[i]^c[i-1];//求前缀异或和
34         b[i] = a[i];
35     }
36     sort(b+1,b+1+n);
37     int q;
38     scanf("%d",&q);
39     for(int i = 1;i<=q;i++){
40         scanf("%d%d",&query[i].l,&query[i].r);
41         query[i].index = i;
42     }
43     sort(query+1,query+1+q,cmp);
44     int cnt = 1;
45     for(int i = 1;i<=n;i++){
46         int index = lower_bound(b+1,b+1+n,a[i])-b-1;
47         if(last[index])
49         last[index] = i;
51         while(query[cnt].r==i && cnt<=q){
52             ans[query[cnt].index] = (c[query[cnt].r]^c[query[cnt].l-1])^(getsum(query[cnt].r)^getsum(query[cnt].l-1));//注意
53             cnt++;
54         }
55     }
56     for(int i = 1;i<=q;i++)
57         printf("%I64d\n",ans[i]);
58     return 0;
59 }
View Code

posted @ 2016-08-07 16:26  张秦遥  阅读(258)  评论(0编辑  收藏