cf 1140e Palindrome-less Arrays

题目大意:给你一个不超过20万的序列,里面每个数都是1到k直接的数,有些是-1,表示这个位置上的数待定。 定义一个序列是“好的”,当这个序列中没有长度为奇数(至少是3)的回文串。问有多少中填法,使得序列是好的。

 

思路;由于是奇数的回文串,所以我们只要考虑是否有长度为3的回文就可以了,那么这个问题就简单了。类似于染色问题,我做了一个dp。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 #define rep(i,a,b) for(int i=a;i<=b;i++) 
 4 #define Rep(i,a,b) for(int i=a;i>=b;i--) 
 5 #define ms(i,a)    memset(a,i,sizeof(a))  
 6 #define gc()       getchar() 
 7 #define ll         long long 
 8 template<class T>void read(T &x){
 9     x=0; char c=0; int w=0; 
10     while (!isdigit(c)) w+=c=='-',c=gc();  
11     while (isdigit(c)) x=x*10+(c^48),c=gc(); 
12     if(w) x=-x;  
13 }
14 int const N=200000+3;  
15 int const mod=998244353;  
16 int n,k,a[N],b[N],m;   
17 ll dp[N][2],f[N][3],pw[N];  
18 ll  solve(){
19     int l=-2,r=-2,num=0;
20     ll ret=1;   
21     b[m+1]=-2;  
22     rep(i,1,m-1) if(b[i]>-1 && b[i+1]>-1 && b[i]==b[i+1]) return 0;  
23     rep(i,1,m+1){
24         if (b[i]==-1) num++; 
25         else{
26             r=b[i];  
27             if(num){
28                 if(l<0 && r<0) ret=ret*pw[num-1]% mod *k %mod;   
29                 else if(l>0 && r>0) {
30                     if(l==r) ret=ret*dp[num][1]% mod;  
31                     else ret=ret*(f[num][1]+f[num][0])% mod;  
32                 }else ret=ret*pw[num]% mod;  
33             }
34             l=b[i]; num=0;  
35         } 
36     }
37     return ret;  
38 }  
39 int main(){
40     read(n); read(k); 
41     rep(i,1,n) read(a[i]);  
42     pw[0]=1; rep(i,1,n) pw[i]=pw[i-1]*(k-1)%mod;  
43     dp[1][0]=0; dp[1][1]=k-1;  
44     rep(i,2,n) dp[i][0]=dp[i-1][1],dp[i][1]=(dp[i-1][0]*(k-1)+dp[i-1][1]*(k-2)) % mod;  
45     f[1][0]=k-2;f[1][1]=0; f[1][2]=1;  
46     rep(i,2,n) {
47         f[i][1]=(f[i-1][0]+f[i-1][2])% mod;  
48         f[i][2]=(f[i-1][0]+f[i-1][1])% mod;  
49         f[i][0]=(f[i-1][0]*(k-3)+  f[i-1][1]*(k-2) +f[i-1][2]*(k-2)) % mod;  
50     }
51     rep(i,1,n) if(i&1) b[++m]=a[i];  
52     ll ans=solve();  
53     m=0;  
54     rep(i,1,n) if(i%2==0) b[++m]=a[i];  
55     ans=ans* solve() % mod;  
56     printf("%lld\n",ans); 
57     return 0; 
58 }
View Code

 

转载于:https://www.cnblogs.com/ZJXXCN/p/10627970.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值