問題の説明
問題の解決策
セット\(opt_ {I、J} (iは[1、N]で\、[1,26])\でj個の\) 区間の代表\([1、I] \) 、終了\(J \)のを執筆。
セット\(exist_ {I、J} (I、Jでの\ [1,26])\) 代表\((i、j)は\ ) に隣接し、場合かどうか\(1 \) 、ありません。
そこ
\ [opt_ {I、J} = \ sum_ {k = 1} ^ {26} opt_ {I-1、K}(exist_ {K、J} = 0)\]
我々が見つかりました\(N- \ル^ {15} 10 \) 、それは確かに再帰的ではないので、それほど行列の最適化
マトリックス\(ベース\)の\(26 \回26 \) A、\(base_ {I、J-exist_ 1} = {I、J} \)
\(\ mathrm {コード} \)
#include<bits/stdc++.h>
using namespace std;
#define int long long
template <typename Tp>
void read(Tp &x){
x=0;char ch=1;int fh;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-'){
fh=-1;ch=getchar();
}
else fh=1;
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
x*=fh;
}
const int mod=1000000007LL;
char s[100007];
int len,n;
int exist[27][27];
int chk(char c){
return c-'a'+1;
}
struct Mat{
int a[27][27],n;
Mat(){
n=26;memset(a,0,sizeof(a));
}
}base,ans;
Mat Mul(Mat a,Mat b){
int q=a.n;
Mat ret;
for(int i=1;i<=q;i++){
for(int j=1;j<=q;j++){
for(int k=1;k<=q;k++){
ret.a[i][j]=(ret.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
}
}
}
return ret;
}
Mat ksm(Mat x,int p){
Mat ret;
for(int i=1;i<=26;i++) ret.a[i][i]=1;
while(p){
if(p&1) ret=Mul(ret,x);p>>=1;
x=Mul(x,x);
}
return ret;
}
int sum;
signed main(){
ios::sync_with_stdio(false);
cin>>n>>(s+1);
if(n==1){
puts("1");return 0;
}
len=strlen(s+1);
for(int i=2;i<=len;i++){
int xx=chk(s[i]),yy=chk(s[i-1]);
exist[yy][xx]=1;
}
for(int i=1;i<=26;i++){
ans.a[1][i]=1;
for(int j=1;j<=26;j++){
if(!exist[i][j]) base.a[i][j]=1;
}
}
ans=Mul(ans,ksm(base,n-1));
for(int i=1;i<=26;i++){
sum=(sum+ans.a[1][i])%mod;
}
cout<<sum<<endl;
return 0;
}