题面在这里

题意:给定一个无向图,从1号节点出发,每次等概率选择连接该节点的一条边走到另一个节点,到达n号节点时,将走过的路径上的所有边权异或起来,求这个异或和的期望

sol

一道期望大火题(表示看了zsy大佬ycb大佬的题解才过去的orz)

递推期望,因为是异或和,按照正常方法会很难,于是考虑按位DP(套路吧),即对于边权在二进制下的每一位分别讨论

设状态的时候需要注意

如果设\(f[x]\)表示从1号节点到达x号节点且异或和为1的概率

那么在转移的时候,因为到达n号节点的时候就已经停止,所以f[n]不能转移;而我们又必须求出\(f[n]\),因此必须先对除n以外的所有点进行计算,再推到n,这样会很麻烦

于是想到倒着推,设\(f[x]\)表示从x号节点到达n号节点且异或和为1的概率,答案为\(f[1]\),虽然说也不能从\(f[n]\)转移,但因为要求解的不是\(f[n]\)所以就让求解变得可行了

通过边进行转移:

\[f[u]=\sum_{v}\frac{f[v]}{d[u]}*[(u,v)==0]+\sum_{v}\frac{1-f[v]}{d[u]}*[(u,v)==1]
\]

意即该位权值为1的点通过0边和该位权值为0的点通过1边到达点u所得的该位权值都是1

由于每个f[u]都和另外的f[v]产生依赖关系,故无法直接递推求解

高斯消元大显身手啦!!!!!!

代码

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
const int mod=1e9+7;
const int N=110;
const double eps=1e-10;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
} int n,m,head[N],nxt[N*N*2],to[N*N*2],val[N*N*2],d[N],cnt;
il void add(int u,int v,int w){
to[++cnt]=v;d[v]++;
val[cnt]=w;
nxt[cnt]=head[u];
head[u]=cnt;
} dd S[35][N][N],ans[35][N],sum;
il bool gauss(int a){
//高斯消元部分
for(RG int i=1;i<=n;i++){
for(RG int j=i;j<=n;j++)
if(abs(S[a][j][i])>eps){
swap(S[a][j],S[a][i]);break;
}
if(abs(S[a][i][i])<=eps)return 0;
for(RG int j=i+1;j<=n;j++){
ans[a][j]-=ans[a][i]*S[a][j][i]/S[a][i][i];
for(RG int k=n;k>=i;k--)
S[a][j][k]-=S[a][i][k]*S[a][j][i]/S[a][i][i];
}
} for(RG int i=n;i;i--){
for(RG int j=i+1;j<=n;j++)
ans[a][i]-=S[a][i][j]*ans[a][j];
ans[a][i]/=S[a][i][i];
} return 1;
} int main()
{
n=read();m=read();
for(RG int i=1,u,v,w,t;i<=m;i++){
u=read();v=read();w=read();t=0;
add(u,v,w);if(u!=v)add(v,u,w);
} //这里是统计系数
for(RG int u=1;u<n;u++){
for(RG int i=0;i<=32;i++)S[i][u][u]+=1.0;
for(RG int i=head[u];i;i=nxt[i]){
RG int v=to[i],t=0;
while(t<=32){
S[t][u][v]+=((val[i]&1)?1:(-1))*1.0/(d[u]*1.0);
ans[t][u]+=((val[i]&1)?1:0)*1.0/(d[u]*1.0);
val[i]>>=1;t++;
}
}
}for(RG int i=0;i<=32;i++)S[i][n][n]+=1.0;
//这样可以保证最后f[n]==0消除f[n]的影响 for(RG int i=0;i<=32;i++)gauss(i); for(RG ll i=0,x=1;i<=32;i++){sum+=ans[i][1]*x;x<<=1;}
//按位统计答案 printf("%.3lf\n",sum);
return 0;
}

注:还有一道[HNOI2013]游走和此题思想类似,题解在这里

[HNOI2011]XOR和路径的更多相关文章

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

    2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 682  Solved: 384[Submit][Stat ...

  2. BZOJ2337: [HNOI2011]XOR和路径

    题解: 异或操作是每一位独立的,所以我们可以考虑每一位分开做. 假设当前正在处理第k位 那令f[i]表示从i到n 为1的概率.因为不是有向无环图(绿豆蛙的归宿),所以我们要用到高斯消元. 若有边i-& ...

  3. BZOJ 2337: [HNOI2011]XOR和路径( 高斯消元 )

    一位一位考虑异或结果, f(x)表示x->n异或值为1的概率, 列出式子然后高斯消元就行了 --------------------------------------------------- ...

  4. BZOJ 2337: [HNOI2011]XOR和路径 [高斯消元 概率DP]

    2337: [HNOI2011]XOR和路径 题意:一个边权无向连通图,每次等概率走向相连的点,求1到n的边权期望异或和 这道题和之前做过的高斯消元解方程组DP的题目不一样的是要求期望异或和,期望之间 ...

  5. [HNOI2011]XOR和路径 && [HNOI2013]游走

    [HNOI2011]XOR和路径 题目大意 具体题目:戳我 题目: 给定一个n个点,m条边的有重边.有自环的无向图,其中每个边都有一个边权. 现在随机选择一条1到n的路径,路径权值为这条路径上所有边权 ...

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

    2337: [HNOI2011]XOR和路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1170  Solved: 683 Description ...

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

    [BZOJ2337][HNOI2011]XOR和路径 Description 题解:异或的期望不好搞?我们考虑按位拆分一下. 我们设f[i]表示到达i后,还要走过的路径在当前位上的异或值得期望是多少( ...

  8. [Wc2011] Xor 和 [HNOI2011]XOR和路径

    Xor F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser  autoint Logout 捐赠本站 Prob ...

  9. LG3211 [HNOI2011]XOR和路径

    题意 题目描述 给定一个无向连通图,其节点编号为 1 到 N,其边的权值为非负整数.试求出一条从 1 号节点到 N 号节点的路径,使得该路径上经过的边的权值的"XOR 和"最大.该 ...

  10. 【BZOJ】2337: [HNOI2011]XOR和路径 期望+高斯消元

    [题意]给定n个点m条边的带边权无向连通图(有重边和自环),在每个点随机向周围走一步,求1到n的期望路径异或值.n<=100,wi<=10^9. [算法]期望+高斯消元 [题解]首先异或不 ...

随机推荐

  1. 从零开始学Python--数据类型之字符串

    一.Python中的数据类型 ·   整数, 如 1 -100 ·   长整数, 是比较大的整数,Python 2里面有long长整数:Python 3里面没有 ·   浮点数 如 1.23.3E-2 ...

  2. Spring boot 整合mybatis

    第一步:创建maven项目并添加spring boot依赖: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...

  3. Qt 如何使用 QImage 设置指定的颜色为透明色?

    Qt 如何使用 QImage 设置指定的颜色为透明色? 需求背景:使用华大身份证读卡器模块读取身份证信息,通过模块读取的图片为 *.BMP 格式,无透明色,故绘制到身份证上无法美观的显示. 通过查询身 ...

  4. Elasticsearch安装使用

    在网上有很多那种ES步骤和问题的解决 方案的,不过没有一个详细的整合,和问题的梳理:我就想着闲暇之余,来记录一下自己安装的过程以及碰到的问题和心得:有什么不对的和问题希望及时拍砖. 第一步:环境 li ...

  5. 【spring-boot】spring aop 面向切面编程初接触

    众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...

  6. session 与 coolie 的区别与联系

    cookie 和session 的区别: session 在服务器端,cookie 在客户端(浏览器) cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当 ...

  7. 用Python实现《芳华》小说中的汉字频率统计

     环境: Python 3的代码,亲测可用. 思路: 是先把每个字符提出来放在列表里:再过滤掉其中的标点符号:最后用字典对某个字出现的频率进行累加. 扩展: 用处很多,稍微改改,既可以用来统计小说或文 ...

  8. Java线程编程中isAlive()和join()的使用详解

    一个线程如何知道另一线程已经结束?Thread类提供了回答此问题的方法. 有两种方法可以判定一个线程是否结束.第一,可以在线程中调用isAlive().这种方法由Thread定义,它的通常形式如下: ...

  9. 20 个 CSS 高级技巧汇总

    原文:https://segmentfault.com/a/1190000003936841 使用技巧会让人变的越来越懒,没错,我就是想让你变懒.下面是我收集的CSS高级技巧,希望你懒出境界. 1. ...

  10. 使用sql语句获取数据库表的信息

    下面的sql语句可以查看表的信息.其中modify_date和create_date可以根据表的修改时间来查看.如果不需要删除后,就能看到所有表的字段信息 ) PERCENT d.name AS 表名 ...