题意
如果一个数组中有
>
1
>1
>1的奇数回文串就是
b
a
d
bad
bad.
数组中
−
1
-1
−1的部分要求被替换成
1
−
k
1-k
1−k的数字,最后得到的不
b
a
d
bad
bad的数组有多少种
题解
如果能保证最小的奇数回文串不存在,就不会存在更大,最小的是
3
3
3。
保证
a
[
i
]
!
=
a
[
i
−
2
]
a[i]!=a[i-2]
a[i]!=a[i−2]。
我们可以发现分奇偶讨论。
每一部分都是 − 1 − 1 − 1 − 1 X − 1 − 1 − 1 − 1 Y − 1 − 1 -1 -1 -1 -1\quad X\quad -1 -1 -1 -1 \quad Y\quad -1-1 −1−1−1−1X−1−1−1−1Y−1−1
对于一个
a
−
1
−
1
−
1
−
1
b
a\quad -1 -1 -1 -1 \quad b
a−1−1−1−1b的片段,
a
、
b
a、b
a、b相同与否得到的答案不一样。
可以用
d
p
dp
dp求解。
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j],
j
=
0
j=0
j=0表示与左右不同,
j
=
1
j=1
j=1表示与左不同,
j
=
2
j=2
j=2表示与右不同。
对于左右不同的情况,转移是:
d
p
[
i
]
[
0
]
=
d
p
[
i
−
1
]
[
1
]
∗
(
k
−
2
)
+
d
p
[
i
−
1
]
[
2
]
∗
(
k
−
2
)
+
d
p
[
i
−
1
]
[
0
]
∗
(
k
−
3
)
dp[i][0]=dp[i-1][1]*(k-2)+dp[i-1][2]*(k-2)+dp[i-1][0]*(k-3)
dp[i][0]=dp[i−1][1]∗(k−2)+dp[i−1][2]∗(k−2)+dp[i−1][0]∗(k−3)
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
2
]
+
d
p
[
i
−
1
]
[
0
]
dp[i][1]=dp[i-1][2]+dp[i-1][0]
dp[i][1]=dp[i−1][2]+dp[i−1][0]
d
p
[
i
]
[
2
]
=
d
p
[
i
−
1
]
[
1
]
+
d
p
[
i
−
1
]
[
0
]
dp[i][2]=dp[i-1][1]+dp[i-1][0]
dp[i][2]=dp[i−1][1]+dp[i−1][0]
答案为
d
p
[
l
e
n
]
[
1
]
+
d
p
[
l
e
n
]
[
0
]
dp[len][1]+dp[len][0]
dp[len][1]+dp[len][0]
左右相同的时候比较简单,就不阐述了。
答案为
d
p
[
l
e
n
]
[
1
]
dp[len][1]
dp[len][1]
我们再分别计算片段,开头可以看做是左右相同的,但是这一片段答案是 d p [ i ] [ 0 ] + d p [ i ] [ 1 ] dp[i][0]+dp[i][1] dp[i][0]+dp[i][1],因为最左边没有其他元素。
如果片段中的
−
1
-1
−1为
0
0
0呢,那么:
左右不同,则是
d
p
1
[
0
]
[
0
]
+
d
p
1
[
0
]
[
1
]
dp1[0][0]+dp1[0][1]
dp1[0][0]+dp1[0][1],答案为
1
1
1
左右相同,则是
d
p
2
[
0
]
[
0
]
dp2[0][0]
dp2[0][0],答案为
0
0
0
符合要求。
#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
typedef long long ll;
using namespace std;
const ll mod = 998244353;
const int maxn = 2e5+500;
int n,k;
ll dp1[maxn][3],dp2[maxn][2];
vector<int>odd,even;
int A[maxn];
int main(){
cin>>n>>k;
dp1[0][1]=1;
dp1[0][0]=dp1[0][2]=0;
for(int i=1;i<=200050;i++){
dp1[i][0]=(dp1[i-1][1]*(k-2))%mod;
dp1[i][0]=(dp1[i][0]+dp1[i-1][2]*(k-2))%mod;
if(k>=3)dp1[i][0]=(dp1[i][0]+dp1[i-1][0]*(k-3))%mod;
dp1[i][1]=(dp1[i-1][2]+dp1[i-1][0])%mod;
dp1[i][2]=(dp1[i-1][1]+dp1[i-1][0])%mod;
}
dp2[0][1]=1;
dp2[0][0]=0;
for(int i=1;i<=200050;i++){
dp2[i][0]=(dp2[i][0]+dp2[i-1][1]*(k-1))%mod;
dp2[i][0]=(dp2[i][0]+dp2[i-1][0]*(k-2))%mod;
dp2[i][1]=(dp2[i-1][0])%mod;
}
ll l=0,r=0;
FOR(i,1,n){
scanf("%d",&A[i]);
if(i%2){
if(A[i]!=-1)odd.push_back(i);
}
else{
if(A[i]!=-1)even.push_back(i);
}
}
if(odd.size()){
l=(dp2[odd[0]/2][0]+dp2[odd[0]/2][1])%mod;
//cout<<l<<endl;
for(int i=0;i<odd.size()-1;i++){
int diff=odd[i+1]-odd[i];
diff=diff/2-1;
// cout<<diff<<endl;
if(A[odd[i]]==A[odd[i+1]]){
l=(l*dp2[diff][0])%mod;
}
else{
l=(l*(dp1[diff][0]+dp1[diff][1])%mod)%mod;
}
}
int g=(n-odd[odd.size()-1])/2;
if(g){
l=(l*(dp2[g][0]+dp2[g][1])%mod)%mod;
}
// cout<<l<<endl;
}
else{
l=k;
for(int i=3;i<=n;i+=2)l=(l*(k-1))%mod;
}
if(even.size()){
r=(dp2[even[0]/2-1][0]+dp2[even[0]/2-1][1])%mod;
for(int i=0;i<even.size()-1;i++){
int diff=even[i+1]-even[i];
diff=diff/2-1;
if(A[even[i]]==A[even[i+1]]){
r=(r*dp2[diff][0])%mod;
}
else{
r=(r*(dp1[diff][0]+dp1[diff][1])%mod)%mod;
}
}
//cout<<r<<endl;
int g=(n-even[even.size()-1])/2;
if(g){
r=(r*(dp2[g][0]+dp2[g][1])%mod)%mod;
}
//cout<<r<<endl;
}
else{
r=k;
for(int i=4;i<=n;i+=2)r=(r*(k-1))%mod;
}
cout<<(l*r)%mod<<endl;
}