zoukankan      html  css  js  c++  java
  • LOJ 6497 图

    LOJ 6497 图

    题意

    有图(n)点,每点可为黑或白,其中一些点颜色已定。

    初时图无边,于每对(i<j),可由(i)(j)连有向边,或不连。

    称黑白相间之路径为交错路径。

    求:有多少种情况交错路径有奇数条或偶数条。

    数据范围:$$nle2*10^5$$

    注:单点也算一条交错路径。

    思路

    在后方新增一点(k+1),交错路径的数量怎么改变。

    显然,新增的交错路径必须以新增的点结尾。

    (sum_x)表示以(x)结尾的交错路径的数量,(S)表示向(k+1)连边的且与(k+1)不同色的点的集合。

    那么,新增交错路径为:

    [(sum_{xin S}{sum_x})+1 ]

    这个应该比较好理解。

    显然,我们只关注这个式子的奇偶性。

    那么,关键在于奇点了。

    对于同色点,我们可以随意连边。

    对于异色且(sum)值为偶数的点,我们也可以随意连边。

    然后,我们就可以(O(n^3))DP了,记录当前有多少个黑色的奇数点,多少个白色的奇数点。

    我们尝试优化一下。

    可以发现,目前对奇数点的处理并不优。

    我们发现,一个奇数点就足以改变整个状态。

    于是,我们任意钦定一个异色奇数点,先不动。

    其他奇数点随意连边。

    观察我们现在的状态和期望转移到的状态有无差异,以此决定是否把钦定的这个点连上。

    此时,我们有(2^{k-1})种连法(除了钦定的点,其他随便连)

    那么,如果没有一个异色奇数点呢?

    无论如何连边,你都将改变交错路径的奇偶性。

    此时,我们有(2^{k})种连法。

    设计状态

    [dp[i][0/1][0/1][0/1] ]

    表示到第(i)个点,此时交错路径总数的奇偶性,有无白色奇数点,有无黑色奇数点

    随便转移即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=998244353;
    const int sz=2e5+7;
    int n,p;
    int a[sz];
    int qp[sz];
    int f[sz][2][2][2];
    void upd(int &x,int y){
    	x=x+y>=mod?x+y-mod:x+y;
    }
    void init(){
    	qp[0]=1;
    	for(int i=1;i<sz;i++) qp[i]=2*qp[i-1]%mod;
    }
    int main(){
    	init();
    	scanf("%d%d",&n,&p);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	f[0][0][0][0]=1;
    	for(int i=0;i<n;i++)
    		for(int k=0;k<=1;k++)
    			for(int x=0;x<=1;x++)
    				for(int y=0;y<=1;y++){
    					int cur=f[i][k][x][y];
    					if(!cur) continue;
    					if(a[i+1]==0||a[i+1]==-1){
    						if(x==0) upd(f[i+1][k^1][x][1],1ll*cur*qp[i]%mod);
    						else{
    							upd(f[i+1][k][x][y],1ll*cur*qp[i-1]%mod);
    							upd(f[i+1][k^1][x][1],1ll*cur*qp[i-1]%mod);
    						}
    					}
    					if(a[i+1]==1||a[i+1]==-1){
    						if(y==0) upd(f[i+1][k^1][1][y],1ll*cur*qp[i]%mod);
    						else{
    							upd(f[i+1][k][x][y],1ll*cur*qp[i-1]%mod);
    							upd(f[i+1][k^1][1][y],1ll*cur*qp[i-1]%mod);
    						}
    					}
    				}
    	int ans=0;
    	upd(ans,f[n][p][0][0]);
    	upd(ans,f[n][p][0][1]);
    	upd(ans,f[n][p][1][0]);
    	upd(ans,f[n][p][1][1]);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    Codeforces Round #544 (Div. 3) C. Balanced Team
    Codeforces Round #544 (Div. 3) B.Preparation for International Women's Day
    Codeforces Round #544 (Div. 3) A.Middle of the Contest
    HDU-2647-Reward
    2015.3.15
    USACO Section 5.1 Musical Themes(枚举)
    [STOI2014]舞伴(dp)
    USACO Section 5.1 Fencing the Cows(凸包)
    2015.3.10
    USACO Section 4.3 Street Race(图的连通性+枚举)
  • 原文地址:https://www.cnblogs.com/river-flows-in-you/p/11862847.html
Copyright © 2011-2022 走看看