SnackDown 2019 - Online Elimination Round Suffix Palindromes

探讨如何计算特定条件下,不存在长度大于1的回文后缀的字符串数量。利用容斥原理,通过递推公式求解总方案数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题链接.

没上OEIS真的是亏了。

题目大意:

问有多少个字符集大小为|S|的长度为n的字符串,不存在一个长度大于1的回文后缀。

1<=n<=1000

1<=|S|<mo=1e9+7

题解:

这种题一看就要容斥原理

首先总方案数是S^n

减去后缀是回文串的,但是我们发现直接减肯定减重。

不妨设 f [ i ] f[i] f[i]表示长度为i的回文串,且它也不存在长度大于1的回文后缀的方案数。

A n s = S n − ∑ i = 2 n f [ i ] ∗ S n − i Ans=S^n-\sum_{i=2}^nf[i]*S^{n-i} Ans=Sni=2nf[i]Sni

那么 f [ i ] f[i] f[i]如何计算呢?

显然可以继续容斥,即总数减去有回文后缀,且这个回文后缀没有大于1的回文后缀。

m = ( n + 1 ) / 2 m=(n+1)/2 m=(n+1)/2
f [ n ] = S m − ∑ i = 1 m f [ i ] ∗ S m − i f[n]=S^m-\sum_{i=1}^mf[i]*S^{m-i} f[n]=Smi=1mf[i]Smi

为什么不用考虑i>m的情况呢,

因为如果后缀i>m是回文的,这个后缀一定有一个大于1的回文后缀。

证明:
因为原串是回文的:
所以s[i…2m-i]是回文的,又因为后缀i是回文的,所以长度是i-(2m-i)+1的后缀也是回文的。

i-(2m-i)+1=2(i-m)+1
因为i>m所以2(i-m)+1>=3

因此后缀i一定还存在长度大于1的回文后缀。

感觉最后的这个点挺难想的,卡了一会儿,毕竟这题Samjia做了1h也没有做出来(小骄傲~)

Code:

#include<cstdio>
#define ll long long
#define fo(i, x, y) for(int i = x; i <= y; i ++)
using namespace std;

const int N = 1e3 + 5;

int n, s, mo;
ll f[N], a[N], ans;

int main() {
	scanf("%d %d %d", &n, &s, &mo);
	a[0] = 1; fo(i, 1, n) a[i] = a[i - 1] * s % mo;
	fo(i, 2, n) {
		int m = i + 1 >> 1;
		f[i] = a[m];
		fo(j, 2, m) f[i] = (f[i] - f[j] * a[m - j] % mo + mo) % mo;
	}
	ans = a[n];
	fo(i, 2, n) ans = (ans - a[n - i] * f[i] % mo + mo) % mo;
	printf("%lld", ans);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值