Scarlet的字符串不可能这么可爱

题目链接:https://www.luogu.org/problemnew/show/P4925

一开始没想出来的一道题目,感觉思想很巧妙的,有很多值得借鉴的地方,所以整理了下来:

首先考虑没有限制合法字符串:

一个很显然的结论就是,对于一个回文字串,如果长度为奇数的话,则必定包含一个长度为3的回文串;若长度为偶数的话,则必定包含一个长度为2的回文串。也就是说对于l>=3且k>=3的情况,我们只需考虑对于每一个位置的字符,使它一定不和前两位字符相同即可。根据数学知识可知:一共有k*(k-1)*(k-2)^(l-2)这么多种方案。

那么如果有限制的话,也就是说已经用了一个字符了,则剩下的总共有(k-1)*(k-2)^(l-2)这么多种方案。

对于其它的情况,由于数据较小,可以打表考虑一下。

code:

#include<iostream>
using namespace std;

typedef long long ll;
ll k, l, s, w;
int p;

ll pow(ll x, ll y) {
	ll ans=1, base=x;
	while (y!=0) {
		if (y&1) ans=(ans*base)%p;
		base=(base*base)%p;
		y>>=1;
	}
	return ans;
}

int work() {
	if (s==0) {
		if (l==1) return k;
		if (l==2) return k*(k-1)%p;
		if (l>=3) {
			if (k>=3) return ((k*(k-1))%p*pow(k-2, l-2))%p;
			else return 0;
		}
	}
	else {
		if (l==1) return 1;
		if (l==2) return k-1;
		if (l>=3) {
			if (k>=3) return ((k-1)*pow(k-2, l-2))%p;
			else return 0;
		}
	}
} 

int main() {
	cin >> k >> l >> p >> s >> w;
	k%=p;
	cout << work();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值