【BZOJ】2337: [HNOI2011]XOR和路径

【算法】期望+高斯消元

【题解】因为异或不能和期望同时运算,所以必须转为加乘

考虑拆位,那么对于边权为1取反,边权为0不变。

E(x)表示从x出发到n的路径xor期望。

对于点x,有E(x)=Σ(1-E(y))(边权1)||E(y)(边权0)/t[x]   t[x]为x的度。

那么有n个方程,整体乘上t[x]确保精度,右项E(x)移到左边——方程可以各种变形。

每次计算完后*(1<<k)就是贡献。

逆推的原因在于n不能重复经过,而1能重复经过,所以如果计算“来源”不能计算n,而计算1也有困难。

所以逆推计算“去向”是最方便的。

那么定义E(n)=0

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=110;
struct edge{int v,w,from;}e[maxn*maxn*2];
int first[maxn],n,m,tot,t[maxn];
long double a[maxn][maxn];
void insert(int u,int v,int w)
{tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;t[u]++;}
void gauss()
{
    for(int i=1;i<=n;i++)
    {
        int r=i;
        for(int j=i+1;j<=n;j++)
        if(fabs(a[j][i])>fabs(a[r][i]))r=j;
        if(r!=i)for(int j=i;j<=n+1;j++)swap(a[r][j],a[i][j]);
        for(int j=i+1;j<=n;j++)
        for(int k=n+1;k>=i;k--)
        a[j][k]-=a[j][i]/a[i][i]*a[i][k];
    }
    for(int i=n-1;i>=1;i--)
    {
        for(int j=i+1;j<=n;j++)
        a[i][n+1]-=a[j][n+1]*a[i][j];
        a[i][n+1]/=a[i][i];
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        insert(u,v,w);if(u!=v)insert(v,u,w);
    }
    long double ans=0;
    for(int k=0;k<30;k++)
    {
        memset(a,0,sizeof(a));
        for(int x=1;x<n;x++)
        {
            for(int i=first[x];i;i=e[i].from)
            {
                if(e[i].w&(1<<k)){a[x][e[i].v]-=1.0;a[x][n+1]-=1.0;}
                else a[x][e[i].v]+=1.0;
            }
            a[x][x]-=t[x];
        }
        a[n][n+1]=0.0;
        gauss();
        ans=(ans+a[1][n+1]*(1<<k));
    }
    printf("%.3Lf",ans);
    return 0;
}

时间: 2025-01-18 07:13:18

【BZOJ】2337: [HNOI2011]XOR和路径的相关文章

【概率DP/高斯消元】BZOJ 2337:[HNOI2011]XOR和路径

2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 682  Solved: 384[Submit][Status][Discuss] Description 几乎是一路看题解过来了.. 拖了一个星期的题目- - 已然不会概率DP(说得好像什么时候会过一样),高斯消元(打一次copy一遍). 发现异或题目的新解决方法:按位处理.. 发现DP新方法:高斯消元. f[k][i]代表第k位权值起点为i到终点时答案

bzoj 2337: [HNOI2011]XOR和路径

Description Input Output Sample Input Sample Output HINT Source Day2 终于把这个史前遗留的坑给填了... 首先异或的话由位无关性,可以按位处理... 那么对于每一位,设f[i]表示从i出发第一次到达n且xor和为1的概率,out[i]为i的出边,那么转移就比较容易了... if(w(i,j)&xxx) f[i]+=(1-f[j)/out[i];// 这条边该位为1,需要xor上0,xor和才为1 else f[i]+=f[j]/

bzoj 2337 [HNOI2011]XOR和路径【高斯消元+dp】

首先,我们发现,因为是无向图,所以相连的点之间是有"依赖性"的,所以不能直接用dp求解. 因为是xor,所以按位处理,于是列线性方程组,设$ x[i] $为点i到n异或和为1的期望,因为从1到n和从n到1一样,所以选择倒着推,即, if(deg[e[i].va]==0) \[ x[u]=\sum_{v}^{v\subset son(u)}\frac{x[v]}{deg[i]} \] else \[ x[u]=\sum_{v}^{v\subset son(u)}\frac{1-x[v])

【BZOJ 2337】 2337: [HNOI2011]XOR和路径(概率DP、高斯消元)

2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1170  Solved: 683 Description Input Output Sample Input Sample Output HINT Source Day2 [分析] 这题终于自己打出来了高斯消元.没有对比代码了... 很心酸啊..调试的时候是完全没有方向的,高斯消元还要自己一步步列式子然后消元解..[为什么错都不知道有时候 这题显然是不能

【BZOJ2337】[HNOI2011]XOR和路径 期望DP+高斯消元

[BZOJ2337][HNOI2011]XOR和路径 Description 题解:异或的期望不好搞?我们考虑按位拆分一下. 我们设f[i]表示到达i后,还要走过的路径在当前位上的异或值得期望是多少(妈呀好啰嗦),设d[i]表示i的度数.然后对于某条边(a,b),如果它的权值是1,那么f[b]+=(1-f[a])/d[a]:如果它的权值是0,那么f[b]+=f[a]/d[a],然后我们移个项,就变成了一堆方程组求解,直接高斯消元. 别忘了f[n]=0! #include <cstdio> #i

BZOJ2337 HNOI2011 XOR和路径

将权值用二进制表示,由于到达n就立即停止,我们定义f[i]表示从i到达n的期望值. 那么显然f[n]=0,对于其他情况,我们列出其转移方程: f[i]+=f[x]/deg[i] 若两边连边当前位为0 f[i]+=(1-f[x])/deg[i] 若两边连边当前位为1 然后就有n-1个方程,高斯消元求解,由于必有唯一解,写起来就方便多了. 最终的答案就是f[1]*2^当前位累加和 1 #include<cstdio> 2 #include<cstdlib> 3 #include<

[HNOI2011]XOR和路径

题面 一道期望大火题(表示看了zsy大佬和ycb大佬的题解才过去的orz) 递推期望,因为是异或和,按照正常方法会很难,于是考虑按位DP(套路吧) 设状态的时候需要注意 如果设f[x]表示从1号节点到达x号节点且异或和为1的概率 那么在转移的时候,因为到达n号节点的时候就已经停止,所以f[n]不能转移;而我们又必须求出f[n],因此必须先对除n以外的所有点进行计算,再推到n,这样会很麻烦 于是想到倒着推,设f[x]表示从x号节点到达n号节点且异或和为1的概率,答案为f1,虽然说也不能从f[n]转

【BZOJ2337】Xor和路径(高斯消元)

[BZOJ2337]Xor和路径(高斯消元) 题面 BZOJ 题解 我应该多学点套路: 对于xor之类的位运算,要想到每一位拆开算贡献 所以,对于每一位拆开来看 好了,既然是按位来算 我们就只需要计算从\(1\)号点开始 到\(n\)的路径中,路径的异或和为\(1\)的概率 显然没法算 还是一样的 考虑高斯消元 对于每一个节点\(i\) \[f[i]=\sum_{w(u,i)=1}\frac{1-f[u]}{op[u]}+\sum_{w(u,i)=1}\frac{f[u]}{op[u]}\] 其

矩阵乘法专题4——bzoj 2326 [HNOI2011] 数学作业 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24963747 [原题] 2326: [HNOI2011]数学作业 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 853  Solved: 473 [Submit][Status] Description [分析]我们按数字的位数来划分.对于K位数,我们就可以专门设计一个矩阵来计算. 然后就是注意细节了. [代码] #include