JZOJ-senior-5957. 【NOIP2018模拟11.7A组】scarborough fair

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HuangXinyue1017/article/details/83895894

Time Limits: 2000 ms Memory Limits: 262144 KB

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

一行一个整数,表示期望不方便程度在模 998244353 的意义下的答案。

Sample Input

3 3
1 2 499122177
2 3 499122177
3 1 499112177

Sample Output

374334134

Data Constraint

对于 15% 的数据,满足 m ≤ 21。
对于另外 35% 的数据,满足 n ≤ 11。
对于 80% 的数据 (包括以上 50% 的数据),满足 n ≤ 14。
对于 100% 的数据,满足 n ≤ 17。

Hint

在这里插入图片描述

Solution

又是期望,加之坑的一匹的样例输入……NOIP2018前心态崩完……
n < = 17 n<=17 ,考虑状压
f s f_s 表示 s s 集合中这些点的联通的概率
正难则反,我们用 1 1 减去不连通的概率
g s g_s 表示 s s 的导出子图中所有边都不连通的概率
f s = 1 t s , l o w b i t ( s ) t f t g s g t g s x o r t f_s=1-\sum_{t\subsetneqq s,lowbit(s)\in t}f_t*\frac{g_s}{g_t*g_{s xor t}}
由于这题卡常,为减少模的次数,代码中 f 1 s = f s g s f1_s=\frac{f_s}{g_s} g 1 s = 1 g s g1_s=\frac{1}{g_s}
求答案类似
时间复杂度 O ( n 3 ) O(n^3)

Code

#include<algorithm>
#include<cstdio>

#define fo(i,a,b) for(int i=a;i<=b;++i)
#define lowbit(x) ((x)&(-x))
#define ll long long

using namespace std;

const int N=25,M=625,K=131072,P=998244353;
int n,m,mx,ans;
int _2[N],v[N],x[M],y[M],p[M];
int g[K],f[K],g1[K],f1[K];

int ksm(int a,int b)
{
	int s=1;
	for(;b;a=(ll)a*(ll)a%P,b>>=1)
		if(b&1) s=(ll)s*(ll)a%P;
	return s;
}

void prepare()
{
	fo(s,0,mx)
	{
		g[s]=1;
		fo(i,1,m) if((_2[x[i]-1]&s)&&(_2[y[i]-1]&s)) g[s]=(ll)g[s]*(ll)p[i]%P;
		g1[s]=ksm(g[s],P-2);
	}
}

void calc()
{
	fo(s,1,mx)
	{
		for(int t=(s-1)&s;t;t=(t-1)&s)//枚举子集
			if(t&lowbit(s)) f[s]=((ll)f[s]+(ll)f1[t]*(ll)g1[s^t]%P)%P;
		f[s]=(ll)f[s]*(ll)g[s]%P;
		f[s]=(1-f[s]+P)%P;
		f1[s]=(ll)f[s]*(ll)g1[s]%P;
		ans=((ll)ans+(ll)f1[s]*(ll)g1[mx^s]%P)%P;
	}
	ans=(ll)ans*(ll)g[mx]%P;
}

int main()
{
	freopen("fair.in","r",stdin);
	freopen("fair.out","w",stdout);
	scanf("%d%d",&n,&m);
	_2[0]=1; fo(i,1,n) _2[i]=_2[i-1]<<1; mx=_2[n]-1;
	fo(i,1,m) scanf("%d%d%d",&x[i],&y[i],&p[i]);
	prepare();
	calc();
	printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/HuangXinyue1017/article/details/83895894
今日推荐