对于求子串个数明显是用dp,对于每添加一个字符ch,必然是多2*dp[i-1]个串,那必然还有重复的串,就是之前ch出现位置的串,需要减去。
对于添加字母,贪心的加上之前出现位置最小的字母。
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#include <sstream>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
const int maxn = 1000000 + 5;
using namespace std;
char s[maxn];
int pre[26];
LL sum[maxn];
int idx(char ch){
return ch - 'a';
}
LL dp[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
scanf("%s",s+1);
int len = (int)strlen(s+1);
memset(pre, 0, sizeof(pre));
memset(dp, 0, sizeof(dp));
dp[0] = 1;
for(int i=1; i<=len; i++){
if(pre[idx(s[i])] == 0)
dp[i] = (dp[i-1] * 2) % mod;
else
dp[i] = (2*dp[i-1] - dp[pre[idx(s[i])]-1] + mod) % mod;
pre[idx(s[i])] = i;
}
for(int i=len+1; i<=len+n; i++){
int id = 0, pos = i;
for(int j=0; j<m; j++){
if(pre[j] < pos){
pos = pre[j];
id = j;
}
}
if(pre[id] == 0)
dp[i] = (dp[i-1] * 2) % mod;
else
dp[i] = (2*dp[i-1] - dp[pos-1] + mod) % mod;
pre[id] = i;
}
printf("%lld\n", dp[n+len] % mod);
}