zoukankan      html  css  js  c++  java
  • Loj 6497「雅礼集训 2018 Day1」图

    $ 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}$ 能取得个好成绩吧

  • 相关阅读:
    树:二叉树
    树:红黑树
    gtest
    VDB R&D
    QML 从入门到放弃
    json parse
    Effective C++ 笔记
    Samples topic
    C++ 11 snippets , 2
    C++ 11 snippets , 1
  • 原文地址:https://www.cnblogs.com/wyzwyz/p/13938386.html
Copyright © 2011-2022 走看看