CF1140E Palindrome-less Arrays(巧妙的递推)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1140E Palindrome-less Arrays(巧妙的递推)相关的知识,希望对你有一定的参考价值。
题意
一个数组有些位置是 ? ? ?,你可以使用 [ 1 , k ] [1,k] [1,k]填充
满足最后对于 i ∈ [ 1 , n − 2 ] i\\in[1,n-2] i∈[1,n−2]有 a i ! = a i + 2 a_i!=a_{i+2} ai!=ai+2,求方案数
我们分成奇数索引构成的数组和偶数索引构成的数组分别考虑
现在设奇数索引构成的数组为 a a a,条件限制相当于相邻元素值不能相同.
考虑到 ? ? ?可能连成一块,这就变得非常麻烦,其实可以把连续的 ? ? ?缩成一个块
设 f [ i ] [ 0 ] f[i][0] f[i][0]表示 ? ? ?块长度为 i i i,且问号块左右两端的数字不相等的方案, f [ i ] [ 1 ] f[i][1] f[i][1]表示两端相等
(注意这里的两端不是问号,是最左边问号左边那个确定的数字)
当从 f [ i − 1 ] [ 0 ] f[i-1][0] f[i−1][0]转移来时,形如a -1 -1 -1…c ,在c前面插入一个数字 b b b变成 f [ i ] [ 0 ] f[i][0] f[i][0]
形如a -1 -1 -1 … b c,此时 b b b有 k − 2 k-2 k−2种取值
当从 f [ i − 1 ] [ 1 ] f[i-1][1] f[i−1][1]转移来时,形如a -1 -1 -1 … a.在最右边插入最右端的数字 b b b(已经被确定)变成a -1 -1 -1 … a b
那么倒数第一个问号只能取 a a a
f [ i ] [ 0 ] = f [ i − 1 ] [ 0 ] ∗ ( k − 2 ) + f [ i − 1 ] [ 1 ] f[i][0]=f[i-1][0]*(k-2)+f[i-1][1] f[i][0]=f[i−1][0]∗(k−2)+f[i−1][1]
f [ i ] [ 1 ] f[i][1] f[i][1]表示两端问号相等的方案
此时 f [ i − 1 ] [ 0 ] f[i-1][0] f[i−1][0]形如a -1 -1 -1… b
考虑在最右边添上一个 a a a变成a -1 -1 -1… b a就变成了 f [ i ] [ 1 ] f[i][1] f[i][1]的方案
f [ i ] [ 1 ] = f [ i − 1 ] [ 0 ] ∗ ( k − 1 ) f[i][1]=f[i-1][0]*(k-1) f[i][1]=f[i−1][0]∗(k−1)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 3e5+10;
const int mod = 998244353;
int n,k,a[maxn],b[maxn],f[maxn][2];
int quick(int x,int n)
{
int ans = 1;
for( ; n ; n>>=1,x=x*x%mod )
if( n&1 ) ans = ans*x%mod;
return ans;
}
int solve(int a[],int n )
{
if( !n ) return 1;
int l = 1, r = n, ans = 0;
while( l<=n && a[l]==-1 ) l++;
while( r>=1 && a[r]==-1 ) r--;
if( l>n ) return quick( k-1,n-1 )*k%mod;
ans = quick( k-1,l-1 )*quick( k-1,n-r )%mod;
int las = l;
for(int i=l+1;i<=r;i++)
{
if( a[i]==-1 ) continue;
else
{
ans = ans*f[i-las-1][a[las]==a[i]]%mod;
las = i;
}
}
return ans;
}
signed main()
{
cin >> n >> k;
f[0][0] = 1, f[0][1] = 0;
for(int i=1;i<=n;i++)
{
f[i][1] = f[i-1][0]*(k-1)%mod;
f[i][0] = ( f[i-1][0]*(k-2)+f[i-1][1] )%mod;
}
// cout << f[2][0] << " --- " << f[2][1] << endl;
for(int i=1;i<=n;i++)
{
int x; cin >> x;
if( i&1 ) a[++a[0]] = x;
else b[++b[0]] = x;
}
cout << solve( a,a[0] )*solve( b,b[0] )%mod;
}
以上是关于CF1140E Palindrome-less Arrays(巧妙的递推)的主要内容,如果未能解决你的问题,请参考以下文章
CF1140E Palindrome-less Arrays(巧妙的递推)
codeforces 1140E Palindrome-less Arrays