题意:求字符集为 ,长度为 的字符串,满足没有任何一个长度超过 的回文连续子串的数量,其中可能指定了字符串的第 位为 。字符集:一个字符串中不同字符的数量。例如,字符集是 的话,你可以认为字符串仅由 三个字母组成。
这题一眼看上去很不可做QAQ,考场上只有20pts。
首先,我们先考虑没有限制的情况,第 位可以放字符集内的所有字符,即有 种情况,而第 位因为不能形成与第 位形成回文,所以可以放 种字符,而第 位因为不能与第 位和第 位形成回文,所以可以放 种字符。而第 位因为不能与第 位和第 位形成回文,所以同样有 种情况。以此类推我们发现从第 位开始,一直到第 位,每一位均有 种情况。得出结论:在不能形成回文串的情况下,每一个字符只需不与前两个相同。所以对于没有限制的情况答案就是 。
然后我们考虑有限制的情况,因为只有一位限制,如果限制在第 位,则第 位有 种情况,第 位到第 位均有 种情况。如果限制在第 位,则第 位有 种情况,第 位到第 为均有 种情况。如果限制在第 位,则第 位有 种情况,第 位有 种情况,第 位到第 为均有 种情况。以此类推对于有一位限制,答案就是 。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll k,l,p,s,w;
ll ksm(ll q,ll w)
{
ll h=1;
while(w)
{
if(w&1)
h=h*q%p;
q=q*q%p;
w>>=1;
}
return h;
}
int main()
{
cin>>k>>l>>p>>s;
k%=p;
if(s!=0)
cin>>w;
if(s==0)
printf("%lld",(k%p*(k-1)%p*ksm(k-2,l-2))%p);
else
printf("%lld",((k-1)%p*ksm(k-2,l-2))%p);
return 0;
}