# CF766 E. Mahmoud and a xor trip

$$F[x][K][0/1]$$表示所有从$$x$$出发的路径中，第$$K$$位为$$0/1$$的情况总数

/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define ll_inf 1e18
#define MK make_pair
#define sqr(x) ((x)*(x))
#define pii pair<int,int>
#define int_inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
}
template<typename T>inline T frd(T x){
int f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
int f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0)	putchar('-'),x=-x;
if (x>9)	print(x/10);
putchar(x%10+'0');
}
const int N=1e5,M=20;
int pre[(N<<1)+10],now[N+10],child[(N<<1)+10],tot;
ll V[N+10],F[N+10][M+10][2];
void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;}
void insert(int x,int y){join(x,y),join(y,x);}
#define T(x) ((V[x]>>K)&1)
void Dfs(int x,int fa){
for (int K=0;K<=M;K++)	F[x][K][T(x)]++;
for (int p=now[x];p;p=pre[p]){
int son=child[p];
if (son==fa)	continue;
Dfs(son,x);
for (int K=0;K<=M;K++){
F[x][K][0]+=F[son][K][T(x)^0];
F[x][K][1]+=F[son][K][T(x)^1];
}
}
}
void Rorate(int x,int fa){
if (fa){
for (int K=0;K<=M;K++){
ll delta[2];
delta[0]=F[fa][K][T(x)^0]-F[x][K][T(fa)^T(x)^0];
delta[1]=F[fa][K][T(x)^1]-F[x][K][T(fa)^T(x)^1];
F[x][K][0]+=delta[0];
F[x][K][1]+=delta[1];
}
}
for (int p=now[x];p;p=pre[p]){
int son=child[p];
if (son==fa)	continue;
Rorate(son,x);
}
}
#undef T
int main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
for (int i=1;i<n;i++){
insert(x,y);
}
Dfs(1,0); Rorate(1,0);
ll Ans=0;
for (int K=0;K<=M;K++){
ll res=0;
for (int i=1;i<=n;i++)	res+=F[i][K][1];
Ans+=(1ll<<K)*res;
}
for (int i=1;i<=n;i++)	Ans+=V[i];
Ans>>=1;
printf("%lld\n",Ans);
return 0;
}

posted @ 2021-07-01 19:47  Wolfycz  阅读(32)  评论(0编辑  收藏  举报