题意:给定一个没有填完的序列,数值为-1表示你可以用 1~k 中的数字去覆盖它,求将该序列填充后,不存在长度为奇数的回文串的方案数

分析:

  1. 使之不存在长度为奇数的回文串,只需要满足不存在长度为3的回文串即可。换句话说:\(a[i] \neq a[i+2]\) 对所有的 \(i\) 成立。可以发现 i 为奇数与 i 为偶数是互不影响的。所以可以把它划分为两个串

    1. 一个串由 $a_1,a_3,a_5, \dots $组成
    2. 另一个串由$ a_2,a_4,a_6,\dots$ 组成
  2. 现在问题转化为了:给定一个序列,将其数值为-1的位置换为1~k中的数字,使得序列中两两相邻数字不同的方案数。不妨换个角度想,任何一组连续的 -1(长度可以为0或1),两边都只有四种情况

    1. 两边都没有数字(即整个串都是-1)
    2. 两边中有一边没有没有(只有整个串的左右两端有这种情况)
    3. 两边的数字相同
    4. 两边的数字不同

    另外我们可以发现,前两种情况可以由后两种情况推出来,所以只需预处理把 0~ (n/2)+1长度的-1串的方案数都预处理出来,问题就迎刃而解了。

  3. 设\(d(i,j)\) 表示长度为 \(i\) 的 -1 串,j 为0 表示两边数字相同,为1表示两边数字不同时的方案数,\(d[0][0] = 0, d[0][1] = 1\), 有转移方程:

    • \(i\) 为奇数

      • \(d[i][0] = d[i/2][0]*d[i/2][0] + (k-1)*d[i/2][1]*d[i/2][1]\)
      • \(d[i][1] = d[i/2][0]*d[i/2][1]*2 + (k-2)*d[i/2][1]*d[i/2][1]\)
    • \(i\) 为偶数
      • \(d[i][0] = (k-1)*d[i-1][1]\)
      • \(d[i][1] = d[i-1][0] + (k-2)*d[i-1][1]%mod\)

对于 i 为奇数的情况,我们可以取出这个序列的中间位置 mid,当 -1 串两端数字相同且都等于 x 时,先假设mid数字与x相同,那就转换为了两个长度为 i/2,序列两端相同 的子问题,然后假设 mid 与 x不同,那么就有(k-1)种方法,可以同样转换成两个长度为 i/2 ,序列两端不同的子问题。当 -1 串两端数字不同时,同理。

预处理d数组之后,就可以对我们之前分好的奇偶串做处理了。思路就是记录上一个不为-1的位置。然后最后做一下特判,就可以得到正确答案了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll d[100010][2];
int a[100010],b[100010];
ll n,k;
ll solve(int *a,ll len){
ll res = 1;
ll last = 0;
for(ll i=1;i<=len;i++){
if(a[i] == -1)continue;
else{
if(i == 1){
last = i;continue;
}
if(last == 0){
res = res * (d[i-2][0] + (k-1)*d[i-2][1])%mod;
}
else{
if(a[i] == a[last]){
res = res * d[i-last-1][0]%mod;
}
else res = res * d[i-last-1][1]%mod;
}
last = i;
}
}
if(last==0){
res = k;
for(int i=2;i<=len;i++)res = (res*(k-1))%mod;
}
else if(last !=len){
res = res * (d[len-last-1][0] + (k-1)*d[len-last-1][1]%mod)%mod;
}
return res;
}
int main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++){
if(i&1)scanf("%d",&a[(i+1)/2]);
else scanf("%d",&b[i/2]);
}
d[0][0] = 0;d[0][1] = 1;
for(int i=1;i<=(n+1)/2;i++){
if(i&1){
int len = i/2;
d[i][0] = (d[len][0] * d[len][0]%mod + (k-1) * d[len][1]%mod * d[len][1]%mod)%mod;
d[i][1] = (d[len][0] * d[len][1]%mod * 2%mod + (k-2) * d[len][1]%mod * d[len][1]%mod)%mod;
}
else{
d[i][0] = (d[i-1][1] * (k-1)) % mod;
d[i][1] = (d[i-1][0] + (k-2) * d[i-1][1]%mod)%mod;
}
}
printf("%lld\n",(solve(a,(n+1)/2)*solve(b,n-(n+1)/2))%mod);
return 0;
}

CF-1140 E - Palindrome-less Arrays的更多相关文章

  1. 不断更新的 ToDo-List

    有些事情要明着写出来才会去干. 这里是一个不断更新的 ToDo-List,大致按照重要度和列出时间排序,已经完成的会画上删除线. 主要着眼短期计划,其中的大部分事务应该在一周内解决,争取不做一只鸽子. ...

  2. 【NOIP2017提高A组模拟9.12】Arrays and Palindrome

    [NOIP2017提高A组模拟9.12]Arrays and Palindrome[SPJ] 题目 Description Input Output Sample Input 1 6 Sample O ...

  3. CF 335B - Palindrome 区间DP

    335B - Palindrome 题目: 给出一个字符串(均有小写字母组成),如果有长度为100的回文子串,输出该子串.否则输出最长的回文子串. 分析: 虽然输入串的长度比较长,但是如果存在单个字母 ...

  4. CF&&CC百套计划2 CodeChef December Challenge 2017 Chef and Hamming Distance of arrays

    https://www.codechef.com/DEC17/problems/CHEFHAM #include<cstdio> #include<cstring> #incl ...

  5. CF 1326 D. Prefix-Suffix Palindrome

    D. Prefix-Suffix Palindrome 题意 给一个字符串 s,求一个字符串 t,t 由 s 的某个前缀以及某个后缀拼接而成,且 t 是回文串,长度不能超过 s.输出最长的 t 分析 ...

  6. CF 335B. Palindrome(DP)

    题目链接 挺好玩的一个题,1Y... #include <cstdio> #include <cstring> #include <iostream> using ...

  7. 【CF】7 Beta Round D. Palindrome Degree

    manacher+dp.其实理解manacher就可以解了,大水题,dp就是dp[i]=dp[i>>1]+1如何满足k-palindrome条件. /* 7D */ #include &l ...

  8. 【agc001d】Arrays and Palindrome

    Portal -->agc001D Description 给你一个\(m\)个数的排列\(A\),这个\(A\)中元素的顺序可以随便调换,\(A\)中的元素的和为\(n\),现在要你构造一个数 ...

  9. Agc001_D Arrays and Palindrome

    传送门 题目大意 给定一个元素和为$N$的有$M$个数的序列$A$,请你可以$A$元素排列的顺序,并需要构造一个有$K$个($K$可以自己定)数的数列,使得任意一个长度为$N$的字符串,若满足:前$A ...

  10. AGC001 D - Arrays and Palindrome【构造】

    把回文串的相等关系连一下,发现最后要求的是一笔画问题 注意到奇数长度的中间有一个单独没有连线的,所以a数组至多有两个奇数值 如果没有奇数,那么b在最前面放一个1,然后把a[1]~a[m-1]放上去,这 ...

随机推荐

  1. Centos下安装pip失败或新装

    Centos安装pip失败: [root@localhost /]# yum -y install pip已加载插件:fastestmirrorRepodata is over 2 weeks old ...

  2. 一份比较完整的gulpfile.js

    var gulp = require('gulp'); //工具 var autoprefixer = require('gulp-autoprefixer'); var include = requ ...

  3. Java怎么把一个.log文件,以text文件方式打开,显示在桌面

    总要有一个开始吧 群里面有一个哥们,问这个问题,索性记录下来, quextion: Java怎么把一个.log文件,以text文件方式打开,显示在桌面 anwser: 这里注意一个问题:拼接路径的时候 ...

  4. 洛谷1220(区间dp)

    要点 处于什么位置的题常用一个套路就是搞完\([l,r]\)以后处于0(l)或1(r)的状态,即\(dp[i][j][0/1]\). 对于此题dp意义为已经搞完\([l,r]\)的时最小的已耗电能,转 ...

  5. csdn自动展开+去广告+净化剪切板+免登陆(如有侵权,立即删博)

    对于csdn的广告大家想必......又没钱充VIP,怎么办,下面是脚本源码: 重要的事说三遍:如有侵权,立即删除!如有侵权,立即删除!如有侵权,立即删除! // ==UserScript== // ...

  6. sqlserver跟据当天年月日日期查询数据库当天数据

    select * from Client where  CONVERT(varchar(100), Cli_Datetime, 23) ='2017-11-06' 在查询之前要对表中datetime类 ...

  7. JS类对象实现继续的几种方式

    0. ES6可以直接使用class,extends来继承. 1.  原型继承 父类: function Persion(name,age){ this.name = name; this.age = ...

  8. linux 安装jdk (二进制文件安装)

    1.下载jdk 此处以1.7 为例 :jdk-7u79-linux-x64.tar.gz 2.通过ssh将安装介质传到服务器 我一般放在 /opt 目录下 3.用tar 命令解压缩   tar -zx ...

  9. JavaScript判断图片是否已经加载完毕的方法汇总

    在网上有很多关于判断图片是否已经加载完毕的文章,但是有的浏览器并不适合,下面小编给大家分享一些有关JavaScript判断图片是否已经加载完毕方法汇总,具体内容如下所示: 一.onload事件 通过监 ...

  10. canvas雪花特效-jQuery插件实现

    这是一款效果十分逼真的html5 canvas下雪场景动画特效插件.这款下雪特效是基于Jason Brown的Snowfall jquery plugin的基础上制作的.在Snowfall jquer ...