$ ext{CSP-S}$ 前写篇题解,涨点 $ ext{RP}$
先考虑对于一张给定的图,我们怎么算到每个点的路径的奇偶方案数
可以发现对于前面的点中,能对到这个点路径奇偶性造成贡献的只可能是异色且路径数为奇数的点(推一下应该可以发现)
如果不存在这样的点,那么方案数就乘上 $2^{i-1}$ (随便连),否则就乘上 $2^{i-2}$
为什么是 $2^{i-2}$ ,目前会 $2$ 种证明
一、
考虑现在考虑到 $n$ 号节点,假设现在前面有 $k$ 个异色奇数点,那么贡献就是
$sumlimits_{i mod 2 = 0 / 1}^{k} C_k^i imes 2^{n-k-1}$
我们知道对于组合数的一行,下指数为奇数的和等于偶数的和,所以就等于
$2^{n-k-1} imes frac{2^{k}}{2}=2^{n-2}$
二、
我们选定最后一个异色奇数点,让其他点先向这个点随便连边,此时对于这个点有且仅有一种连边方案使得该点为奇或偶
所以方案数是乘上 $2^{n-2}$ (当前点编号为 $n$ )
然后就可以 $ ext{DP}$ 了,设 $f[i][0/1][0/1][0/1]$ 为枚举到第 $i$ 个点,是否有白色奇数点,是否有黑色奇数点,路径数总和是奇偶的方案数
直接按上面的转移即可
$code$ :
#include<cstdio> #include<cctype> #define maxn 202202 #define mod 998244353 inline int read(){ int r=0,f=0; char c; while(!isdigit(c=getchar()))f|=(c=='-'); while(isdigit(c))r=(r<<1)+(r<<3)+(c^48),c=getchar(); return f?-r:r; } int n,p,c[maxn]; long long ans,p2[maxn],f[maxn][2][2][2]; int main(){ n=read(),p=read(); p2[0]=1; for(int i=1;i<=n;i++){ c[i]=read(); p2[i]=p2[i-1]*2%mod; } f[0][0][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) for(int o=0;o<2;o++){ if(!f[i-1][j][k][o])continue; long long val=f[i-1][j][k][o]; if(c[i]!=1){ if(k){ (f[i][j][k][o]+=val*p2[i-2]%mod)%=mod; (f[i][j|1][k][o^1]+=val*p2[i-2]%mod)%=mod; } else (f[i][j|1][k][o^1]+=val*p2[i-1]%mod)%=mod; } if(c[i]){ if(j){ (f[i][j][k][o]+=val*p2[i-2]%mod)%=mod; (f[i][j][k|1][o^1]+=val*p2[i-2]%mod)%=mod; } else (f[i][j][k|1][o^1]+=val*p2[i-1]%mod)%=mod; } } for(int i=0;i<2;i++) for(int j=0;j<2;j++) (ans+=f[n][i][j][p])%=mod; printf("%lld ",ans); return 0; }
最后希望 $ ext{CSP-S} ext{2020}$ 能取得个好成绩吧