• 题解-CF1140E Palindrome-less Arrays


    CF1140E Palindrome-less Arrays

    (n)(k)(n) 个数的序列 (a)。把 (a) 中的 (-1) 替换成 ([1,k]) 之间的整数。求使 (a) 中不存在长度为奇数的回文串的方案数。

    数据范围:(2le n,kle 2cdot 10^5)(a_i=-1{ m~or~}a_iin[1,k])


    题目限制即不能有 (a_i=a_{i-2})

    (b_i=a_{2i},c_i=a_{2i-1})

    答案为序列 (b)(c) 填成相邻两数不等的方案数积


    如填 (x,-1,-1,...,-1,y) 这段 (i)(-1) 使相邻两数不等:

    (f_i) 表示 (x=y) 的填法方案数,(g_i) 表示 (x ot=y) 的填法方案数。

    [f_i= egin{cases} 0&(i=0)\ g_{i-1}(k-1)&{ m else}\ end{cases}\\ g_i= egin{cases} 1&(i=0)\ g_{i-1}(k-2)+f_{i-1}&{ m else}\ end{cases} ]

    最后把每段 (-1) 的答案乘起来就是填 (b,c) 的方案数。

    边界的处理具体看代码。


    • 代码
    #include <bits/stdc++.h>
    using namespace std;
    
    //Start
    typedef long long ll;
    typedef double db;
    #define mp(a,b) make_pair(a,b)
    #define x first
    #define y second
    #define b(a) a.begin()
    #define e(a) a.end()
    #define sz(a) int((a).size())
    #define pb(a) push_back(a)
    const int inf=0x3f3f3f3f;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    
    //Data
    const int N=2e5;
    const int mod=998244353;
    int n,k,a[N+7];
    
    //DP
    int f[2][(N<<1)+7]; 
    int bb,b[(N>>1)+7],cc,c[(N>>1)+7];
    void Pre(){
    	f[0][0]=0,f[1][0]=1;
    	for(int i=1;i<=(n>>1)+1;i++){
    		f[0][i]=(ll)f[1][i-1]*(k-1)%mod;
    		f[1][i]=((ll)f[1][i-1]*(k-2)%mod+f[0][i-1])%mod;
    	}
    }
    int DP(int cnt,int s[]){
    	int len=0,lst=0,res=1;
    	for(int i=1;i<=cnt;i++){
    		if(s[i]==-1) len++;
    		else {
    			if(len){
    				if(!lst) res=(ll(k-1)*f[1][len-1]+f[0][len-1])%mod*res%mod;
    				else if(lst==s[i]) res=(ll)f[0][len]*res%mod;
    				else res=(ll)f[1][len]*res%mod;
    			}
    			len=0,lst=s[i];
    		}
    	}
    	if(len){
    		if(!lst){
    			if(len==1) res=k;
    			else res=(ll(k-1)*f[1][len-2]+f[0][len-2])*k%mod*res%mod;
    		} else res=(ll(k-1)*f[1][len-1]+f[0][len-1])%mod*res%mod;
    	}
    	return res;
    }
    
    //Main
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		if(~a[i]&&i-2>=1&&a[i]==a[i-2]) return puts("0"),0;
    		if(i&1) c[++cc]=a[i];
    		else b[++bb]=a[i];
    	}
    	Pre();
    	printf("%d
    ",(ll)DP(cc,c)*DP(bb,b)%mod);
    	return 0;
    }
    
    

    祝大家学习愉快!

  • 相关阅读:
    textspan 转连接
    showDialog 必须Stateful
    SliverList , SliverFixedExtentList
    sliver
    [UWP]UIElement.Clip虽然残废,但它还可以这样玩
    [UWP]用Win2D和CompositionAPI实现文字的发光效果,并制作动画
    [UWP]用Win2D实现镂空文字
    [UWP]通过自定义XamlCompositionBrushBase实现图片平铺
    [UWP]使用Win2D的BorderEffect实现图片的平铺功能
    [UWP]使用CompositionAPI的翻转动画
  • 原文地址:https://www.cnblogs.com/George1123/p/12966010.html
Copyright © 2020-2023  润新知