题解:P4925 [1007] Scarlet的字符串不可能这么可爱

Solution P4925

Idea

先考虑没有限制。

这里我们用一种颜色代表一种字符。

第三个字符应该填什么?显然不能是红或者是蓝。有剩余 k2k-2 种选择。

接下来第四个肯定不能填蓝或者绿,但是可以填红

可能会有人问:如果填和前面相同的颜色不会出现更长的回文串吗?

不会。因为我们在上面已经保证了不会存在长度为 2233 的回文串,所以更长的更不可能存在。

计算答案:第一个可以选 kk 种颜色,第二个可以选 k1k-1 种,剩下 l2l-2 个都是 k2k-2 种,答案就是 k(k1)(k2)l2k(k-1)(k-2)^{l-2}

如果加上了限制呢?可以这么理解:

假如第 ii 个位置已经规定是红色,我们可以先往后填,填第 i+1i+1 个位置,显然有 k1k-1 种方案,再往后填就不难发现等价于没有限制的情况。这一部分的答案数是 (k1)(k2)li1(k-1)(k-2)^{l-i-1}

然后往前填。

不难发现,第 i1i-1 个位置填颜色的时候,因为第 ii 个和第 i+1i+1 个都已经填好了,所以它只有 k2k-2 种填法。第 i2i-2 个位置填颜色的时候,因为第 i1i-1 个和第 ii 个都已经填好了,所以它也只有 k2k-2 种填法。以此类推,当第 jj 个位置填色的时候,因为第 j+1j+1 个和第 j+2j+2 个都已经填好了,所以它只有 k2k-2 种填法。由乘法原理,这一部分的答案是 (k2)i1(k-2)^{i-1} 种。

两个答案相乘,得答案为 (k1)(k2)l2(k-1)(k-2)^{l-2}

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int l,k,s,mod;
long long ans;
long long qpow(long long a,long long b){
	long long res=1;
	while(b){
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}
int m,n;
signed main(){
	scanf("%lld%lld%lld%lld",&k,&l,&mod,&s);
	k%=mod;
	m=((k-1)%mod+mod)%mod;
	n=((k-2)%mod+mod)%mod;
	if(s)printf("%lld",1ll*m*qpow(n,l-2)%mod);
	else printf("%lld",1ll*(k*m%mod)*(qpow(n,l-2)%mod)%mod);
	return 0;
}

Tip

  1. 题目输入是 55 个数,为什么只输入了 44 个?

我们发现各个字符之间是等价的,所以是第几种并没有必要知道,ww 也就可有可无了。

输入 44 个是评测的特性:如果实际程序输入数比给定输入数少,会优先选择靠前的输入。变式一下,如果 wwss 之前输入,便不能省略了。也就是虽然输入文件中给定了 ww,但是我们没有选择要它。

  1. 为什么 #define int long longsigned main

这道题不用这句话会获得 5050 分。这句话的作用是把所有 int 型变量定义成 long long 型,防止爆 int

但是这句话也有副作用。int main() 不能定义成 long long main()。并且有些时候程序会因此 MLE 或 WA 等。所以不到万不得已不要用这个。

  1. 为什么有 m=((k-1)%mod+mod)%mod;n=((k-2)%mod+mod)%mod;

C++ 中,负数取模是负数。如果这题 kk00,则 k1k-1 就是负数,会出错,所以把它单独拿出来。

posted @   Weslie_qwq  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示