TJOI D1T1,难度不大,还能下手。
任何相邻不能出现,相当于给了十万个限制。然后计数。
当我们一筹莫展的时候,我们发现了数据范围。n好大哦。这么大一般就是矩阵快速幂了呀。
然后我们想起来字符串的矩阵状态往往是字符到另一个字符的方案数。矩阵相乘相当于在两个字符中间放东西。
那我们的初始矩阵就是两个字符之间不放东西。那合法的就是1,不合法就是0。
所以n次矩阵表示长度为n+1的字符串。那初始矩阵的n-1次方就是我们要的答案了。
把整个矩阵地东西加起来就是方案。
注意:小心初始化。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
char ch[100003];
const int mod=1e9+7;
struct node{
int a[28][28];
node operator *(const node &b){
node ans;memset(ans.a,0,sizeof(ans));
for(int i=0;i<26;i++){
for(int j=0;j<26;j++){
for(int k=0;k<26;k++){
ans.a[i][j]=(ans.a[i][j]+a[i][k]*b.a[k][j]%mod)%mod;
}
}
}
return ans;
}
};
node jzksm(node a,int b){
node sum=a;--b;if(!b)return sum;
while(b){
if(b&1)sum=sum*a;a=a*a;b>>=1;
}return sum;
}
signed main(){
cin>>n;scanf("%s",ch+1);
if(n==1){
cout<<"26";return 0;
}
node mat;
for(int i=0;i<26;i++){
for(int j=0;j<26;j++)mat.a[i][j]=1;
}
int len=strlen(ch+1);
for(int i=1;i<len;i++){
mat.a[ch[i]-'a'][ch[i+1]-'a']=0;
}
// for(int i=0;i<26;i++){
// for(int j=0;j<26;j++){
// cout<<mat.a[i][j]<<" ";
// }cout<<endl;
// }
mat=jzksm(mat,n-1);int ans=0;
for(int i=0;i<26;i++){
for(int j=0;j<26;j++){
ans=(ans+mat.a[i][j])%mod;
}
}cout<<ans;return 0;
}