codeforces 766E Mahmoud and a xor trip

题目链接:http://codeforces.com/problemset/problem/766/E


大意,给出一个$n$个点的树,每个点都有一个权值,令$Disx$为$u$到$v$路径上的异或和求:

$${\sum _{i=1}^{n-1}\sum _{j=i}^{n}Disx(i,j)}$$


 

 枚举我当前处理的是这个二进制位上第$k$位的值,就只需要统计每个点的子树中有多少个点到当前点的第$k$位的异或和为$0$,为$1$的分别有多少个,统计答案即可。
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 using namespace std;
 9 #define maxn 1000100
10 #define llg long long 
11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
12 llg n,m,k,wei,val[maxn],ans;
13 vector<llg>a[maxn];
14 
15 struct node
16 {
17     llg v1,v2;
18 };
19 
20 void init()
21 {
22     cin>>n;
23     for (llg i=1;i<=n;i++) scanf("%lld",&val[i]),ans+=val[i];
24     llg x,y;
25     for (llg i=1;i<n;i++)
26     {
27         scanf("%lld%lld",&x,&y);
28         a[x].push_back(y),a[y].push_back(x);
29     }
30 }
31 
32 node dfs(llg x,llg fa)
33 {
34     llg w=a[x].size(),v;
35     node now;
36     now.v1=now.v2=0;
37     if (val[x]&wei) now.v1=1;else now.v2=1;
38     for (llg i=0;i<w;i++) 
39     {
40           v=a[x][i];
41         if (v==fa) continue;
42         node ne=dfs(v,x);
43         ans+=now.v1*ne.v2*wei,ans+=now.v2*ne.v1*wei;
44         if (val[x]&wei) now.v1+=ne.v2,now.v2+=ne.v1; else now.v1+=ne.v1,now.v2+=ne.v2;     
45     }
46     return now;
47 }
48 
49 int main()
50 {
51     yyj("E");
52     init();
53     for (k=0;k<=20;k++)
54     {
55         wei=(1<<k);
56         dfs(1,-1);
57     }
58     cout<<ans;
59     return 0;
60 }

 

posted @ 2017-02-08 23:00  №〓→龙光←  阅读(299)  评论(0编辑  收藏  举报