居然没被卡精度,高斯消元居然一边写对了,sb错误居然没犯。。
如此傻逼的我也能1A真是感动。
因为要求的是
xor
的期望,我们可以按位计算每位的期望再相加。
考虑每一位,我们令
d[i]
表示点
i
的出度,我们令
然后我们可以高斯消元来解这个方程。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 105
#define M 10005
#define eps 1e-8
using namespace std;
int n,m,cnt;
double ans,a[N][N];
int head[N],d[N];
int next[M<<1],list[M<<1],key[M<<1];
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
inline void insert(int x,int y,int z)
{
d[x]++;
next[++cnt]=head[x];
head[x]=cnt;
list[cnt]=y;
key[cnt]=z;
}
inline void Gauss()
{
int y;
for (int i=1;i<n;i++)
{
for (y=i;y<n;y++)
if (fabs(a[y][i])>eps) break;
if (y>=n) continue;
if (y!=i)
for (int j=1;j<=n+1;j++) swap(a[i][j],a[y][j]);
double t=a[i][i];
for (int j=1;j<=n+1;j++) a[i][j]/=t;
for (int j=1;j<n;j++)
if (j!=i)
{
double t=a[j][i];
for (int k=1;k<=n+1;k++)
a[j][k]-=a[i][k]*t;
}
}
}
int main()
{
n=read(); m=read();
for (int i=1;i<=m;i++)
{
int u=read(),v=read(),w=read();
insert(u,v,w);
if (u!=v) insert(v,u,w);
}
for (int k=0;k<=30;k++)
{
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++) a[i][i]+=(double)d[i];
for (int x=1;x<n;x++)
for (int i=head[x];i;i=next[i])
if (key[i]&(1<<k)) a[x][list[i]]+=1.0,a[x][n+1]+=1.0;
else a[x][list[i]]-=1.0;
Gauss();
ans+=a[1][n+1]*(1<<k);
}
printf("%.3lf\n",ans);
return 0;
}