[HNOI2011]XOR和路径

题解:

挺水的一道题目吧

首先^显然不能直接考虑,那么就按位考虑

然后就是一个裸的高斯消元算期望的题目

eps定1e-7wa了,还得1e-9

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define N 11000
#define NN 105
#define ll long long
vector<ll> ff[NN][NN];
double f[NN][NN];
bool p[NN];
const double eps=1e-9;
ll n,m;
ll pd(ll x,ll y)
{
  if ((x>>(y-1))&1) return 1;else return 0;
}
void Gauss()
{
  ll now;double ff;
  for (ll i=0;i<n;i++)
  {
    now=i;
    for (ll j=i;j<n;j++)
      if (fabs(f[now][i])<fabs(f[j][i])) now=j;
    if (now!=i)
      for (ll j=0;j<=n;j++) swap(f[now][j],f[i][j]);
    for (ll j=0;j<n;j++)
      if (j!=i&&fabs(f[j][i])>eps)
      {
        ff=f[j][i]/f[i][i];
        for (ll k=0;k<=n;k++)
          f[j][k]-=ff*f[i][k];
      }
  }
  for (ll i=0;i<n;i++) f[i][n]/=f[i][i];
}
int main()
{
  freopen("noip.in","r",stdin);
  freopen("noip.out","w",stdout);
  std::ios::sync_with_stdio(false);
  cin>>n>>m;
  ll c,d,e;
  for (ll i=1;i<=m;i++)
  {
    cin>>c>>d>>e;
    ff[c][d].push_back(e);
    if (c!=d) ff[d][c].push_back(e);
  }
  double ans=0;
  for (ll i=1;i<=40;i++)
  {
    memset(f,0,sizeof(f));
    for (ll i1=1;i1<=n-1;i1++)
    {
      ll x,o=0;
      for (ll j1=1;j1<=n;j1++)
      {
        x=ff[i1][j1].size();
        for (ll j=0;j<x;j++)
        {
          if (pd(ff[i1][j1][j],i))
            f[i1-1][j1-1]-=1,f[i1-1][n]-=1;
          else f[i1-1][j1-1]+=1;
        }
        o+=x;
      }
      for (ll j1=1;j1<=n+1;j1++)
        f[i1-1][j1-1]/=o;
      f[i1-1][i1-1]-=1;
    }
    f[n-1][n-1]=1; f[n-1][n]=0;
    Gauss();
    ans+=f[0][n]*(1<<(i-1));
  }
  printf("%.3f",ans);
  return 0;
} 

 

posted @ 2018-04-03 23:00  尹吴潇  阅读(143)  评论(0编辑  收藏  举报