ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU 5955 Guessing the Dice Roll(AC自动机,高斯消元,概率生成函数)

2020-06-01 21:04:40  阅读:313  来源: 互联网

标签:Guessing AC ... Ai hs rep Aj maxn 高斯消


题目
加强版

你以为我会写AC自动机?对不起这题的加强版只用哈希还只有40行
说实话概率生成函数是个很古老的方法了。
设字符集大小为mmm,字符串下标从1开始。
Fi(x)=j=1P(ji)xjF_i(x) = \sum_{j=1} P(游戏在长度为j的时候玩家i胜利)x^jFi​(x)=∑j=1​P(游戏在长度为j的时候玩家i胜利)xj
G(x)=j=1P(j)xjG(x) = \sum_{j=1} P(游戏在长度为j的时候仍未结束)x^jG(x)=∑j=1​P(游戏在长度为j的时候仍未结束)xj
对于每个串AiA_iAi​,我们在一个未结束的状态后加入它,必定结束,但是结束的时间不同,可能串还没加完就结束了。
所以有:
G(x)(xm)Ai=j=1nk=1min(Ai,Aj)[Ai,1...k=Aj,Ajk+1...Aj]Fj(x)(xm)AikG(x)(\frac x{m})^{|A_i|} = \sum_{j=1}^n \sum_{k=1}^{\min(|A_i|,|A_j|)} [A_{i,1...k} = A_{j,|A_j|-k+1...|A_j|}]F_j(x)(\frac xm)^{|A_i|-k}G(x)(mx​)∣Ai​∣=∑j=1n​∑k=1min(∣Ai​∣,∣Aj​∣)​[Ai,1...k​=Aj,∣Aj​∣−k+1...∣Aj​∣​]Fj​(x)(mx​)∣Ai​∣−k
我们O(n3)O(n^3)O(n3)用哈希算出所有的[Ai,1...k=Aj,Ajk+1...Aj][A_{i,1...k} = A_{j,|A_j|-k+1...|A_j|}][Ai,1...k​=Aj,∣Aj​∣−k+1...∣Aj​∣​]。
那么第iii个玩家胜利的概率为j=0P(ji)=Fi(1)\sum_{j=0} P(游戏在长度为j的时候玩家i胜利) = F_i(1)∑j=0​P(游戏在长度为j的时候玩家i胜利)=Fi​(1)
将上面所有等式用x=1x=1x=1带入可以得到nnn个方程和n+1n+1n+1个变量(包括G(1)G(1)G(1))。
然后加入i=1nFi(1)=1\sum_{i=1}^n F_i(1) = 1∑i=1n​Fi​(1)=1这个等式就可以高斯消元解方程了。

AC Code\mathcal AC \ CodeAC Code

#include<bits/stdc++.h>
#define maxn 305
#define LL long long
#define db double
#define S 131ll
#define eps 1e-13
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
using namespace std;

int n,m;
char s[maxn][maxn];
LL hs[maxn][maxn],pw[maxn];
LL calc(LL *hs,int a,int b){ return hs[b] - hs[a-1] * pw[b-a+1]; }
db a[maxn][maxn],pw2[maxn];

int main(){
	scanf("%d%d",&n,&m);
	pw[0] = pw2[0] = 1;
	rep(i,1,max(n,m)) pw[i] = pw[i-1] * S , pw2[i] = pw2[i-1] * 2;
	rep(i,1,n){
		scanf("%s",s[i]+1);
		rep(j,1,m) hs[i][j] = hs[i][j-1] * S + s[i][j];
	}
	rep(i,1,n) a[0][i] = 1 , a[i][0] = 1;a[0][n+1] = 1;
	rep(i,1,n) rep(j,1,n) rep(k,1,m) if(calc(hs[i],1,k) == calc(hs[j],m-k+1,m))
		a[i][j] -= pw2[k];
	rep(i,0,n){
		rep(j,i+1,n) if(fabs(a[j][i]) > fabs(a[i][i])) swap(a[j],a[i]);
		rep(j,i+1,n){
			db t = a[j][i] / a[i][i];
			rep(k,i,n+1)
				a[j][k] -= a[i][k] * t;
		}
	}
	per(i,n,0){
		rep(j,i+1,n) a[i][n+1] -= a[i][j] * a[j][n+1];
		a[i][n+1] /= a[i][i];
	}
	rep(i,1,n) printf("%.10lf\n",a[i][n+1]);
}

标签:Guessing,AC,...,Ai,hs,rep,Aj,maxn,高斯消
来源: https://blog.csdn.net/qq_35950004/article/details/106443774

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有