CF1140E Palindrome-less Arrays
我觉得这道题非常有前途.......
题意:给定一个填了一半的数组,你要把它补完,使之不存在奇回文串,求方案数。字符集为k。
n,k<=20w
解:不能有长为三的回文串。也就是不能有两个相隔1的数相同。
发现奇偶下标互相独立,抽出来就是不能有两个相邻的数相同。
我们可以设f[i][0]表示第i位填的跟之后第一个非空位置不同的方案数,f[i][1]是相同。
转移的时候,反正我个大SB分8类分类讨论,还要考虑后面没有非空位置的情况......
1 #include <bits/stdc++.h> 2 3 typedef long long LL; 4 const int N = 200010; 5 const LL MO = 998244353; 6 7 int a[N], n, k, nex[N]; 8 LL f[N][2]; 9 10 int main() { 11 int cnt = 0; 12 scanf("%d%d", &n, &k); 13 14 for(int i = 1; i <= n; i++) { 15 scanf("%d", &a[i]); 16 if(i >= 3 && a[i] == a[i - 2] && a[i] != -1) { 17 puts("0"); 18 return 0; 19 } 20 } 21 22 23 for(int i = n; i >= 1; i--) { 24 if(a[i] != -1) nex[i] = a[i]; 25 else nex[i] = nex[i + 2]; 26 } 27 LL ans = 1; 28 f[0][0] = f[0][1] = 1; 29 for(int i = 1; i <= n; i += 2) { 30 if(a[i] != -1) continue; 31 if(i - 2 < 1 && i + 2 > n) { 32 ans *= k; 33 } 34 else if(i - 2 < 1 && a[i + 2] == -1) { 35 f[i][0] = nex[i] ? k - 1 : k; 36 f[i][1] = nex[i] ? 1 : 0; 37 } 38 else if(i - 2 < 1) { 39 ans = ans * (k - 1) % MO; 40 } 41 else if(i + 2 > n && a[i - 2] == -1) { 42 ans = ans * f[i - 2][0] % MO * (k - 1) % MO; 43 } 44 else if(i + 2 > n) { 45 ans = ans * (k - 1) % MO; 46 } 47 else if(a[i + 2] != -1 && a[i - 2] != -1) { 48 ans = ans * (a[i - 2] == a[i + 2] ? k - 1 : k - 2) % MO; 49 } 50 else if(a[i - 2] != -1 && a[i + 2] == -1) { 51 f[i][0] = ((a[i - 2] == nex[i] || !nex[i]) ? k - 1 : k - 2); 52 f[i][1] = ((a[i - 2] == nex[i] || !nex[i]) ? 0 : 1); 53 } 54 else if(a[i - 2] == -1 && a[i + 2] != -1) { 55 ans = ans * ((f[i - 2][0] * (k - 2) % MO + f[i - 2][1] * (k - 1) % MO) % MO) % MO; 56 } 57 else { 58 f[i][0] = (f[i - 2][1] * (k - 1) % MO + f[i - 2][0] * (nex[i] ? k - 2 : k - 1) % MO) % MO; 59 f[i][1] = nex[i] ? f[i - 2][0] : 0; 60 } 61 } 62 LL temp = ans; ans = 1; 63 for(int i = 2; i <= n; i += 2) { 64 if(a[i] != -1) continue; 65 if(i - 2 < 1 && i + 2 > n) { 66 ans *= k; 67 } 68 else if(i - 2 < 1 && a[i + 2] == -1) { 69 f[i][0] = nex[i] ? k - 1 : k; 70 f[i][1] = nex[i] ? 1 : 0; 71 } 72 else if(i - 2 < 1) { 73 ans = ans * (k - 1) % MO; 74 } 75 else if(i + 2 > n && a[i - 2] == -1) { 76 ans = ans * f[i - 2][0] % MO * (k - 1) % MO; 77 } 78 else if(i + 2 > n) { 79 ans = ans * (k - 1) % MO; 80 } 81 else if(a[i + 2] != -1 && a[i - 2] != -1) { 82 ans = ans * (a[i - 2] == a[i + 2] ? k - 1 : k - 2) % MO; 83 } 84 else if(a[i - 2] != -1 && a[i + 2] == -1) { 85 f[i][0] = ((a[i - 2] == nex[i] || !nex[i]) ? k - 1 : k - 2); 86 f[i][1] = ((a[i - 2] == nex[i] || !nex[i]) ? 0 : 1); 87 } 88 else if(a[i - 2] == -1 && a[i + 2] != -1) { 89 ans = ans * ((f[i - 2][0] * (k - 2) % MO + f[i - 2][1] * (k - 1) % MO) % MO) % MO; 90 } 91 else { 92 f[i][0] = (f[i - 2][1] * (k - 1) % MO + f[i - 2][0] * (nex[i] ? k - 2 : k - 1) % MO) % MO; 93 f[i][1] = nex[i] ? f[i - 2][0] : 0; 94 } 95 } 96 97 printf("%lld\n", ans * temp % MO); 98 return 0; 99 }