【CROC 2016 - Elimination RoundE】【DP】Intellectual Inquiry 长度为m字符串后添加n位最大本质不同子串个数

Intellectual Inquiry
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After getting kicked out of her reporting job for not knowing the alphabet, Bessie has decided to attend school at the Fillet and Eggs Eater Academy. She has been making good progress with her studies and now knows the first k English letters.

Each morning, Bessie travels to school along a sidewalk consisting of m + n tiles. In order to help Bessie review, Mr. Moozing has labeled each of the first m sidewalk tiles with one of the first k lowercase English letters, spelling out a string t. Mr. Moozing, impressed by Bessie's extensive knowledge of farm animals, plans to let her finish labeling the last n tiles of the sidewalk by herself.

Consider the resulting string s (|s| = m + n) consisting of letters labeled on tiles in order from home to school. For any sequence of indices p1 < p2 < ... < pq we can define subsequence of the string s as string sp1sp2... spq. Two subsequences are considered to be distinct if they differ as strings. Bessie wants to label the remaining part of the sidewalk such that the number of distinct subsequencesof tiles is maximum possible. However, since Bessie hasn't even finished learning the alphabet, she needs your help!

Note that empty subsequence also counts.

Input

The first line of the input contains two integers n and k (0 ≤ n ≤ 1 000 000, 1 ≤ k ≤ 26).

The second line contains a string t (|t| = m, 1 ≤ m ≤ 1 000 000) consisting of only first k lowercase English letters.

Output

Determine the maximum number of distinct subsequences Bessie can form after labeling the last n sidewalk tiles each with one of the first k lowercase English letters. Since this number can be rather large, you should print it modulo 109 + 7.

Please note, that you are not asked to maximize the remainder modulo 109 + 7! The goal is to maximize the initial value and then print the remainder.

Examples
input
1 3
ac
output
8
input
0 2
aaba
output
10
Note

In the first sample, the optimal labeling gives 8 different subsequences: "" (the empty string), "a", "c", "b", "ac", "ab", "cb", and "acb".

【CROC 2016 - Elimination RoundE】【DP】Intellectual Inquiry 长度为m字符串后添加n位最大本质不同子串个数_第1张图片

In the second sample, the entire sidewalk is already labeled. The are 10 possible different subsequences: "" (the empty string), "a", "b", "aa", "ab", "ba", "aaa", "aab", "aba", and "aaba". Note that some strings, including "aa", can be obtained with multiple sequences of tiles, but are only counted once.

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e6+10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int m, n, k;
char s[N];
int f[N+N];		//f[i]表示尾端点在[i]条件下的本质不同子串个数
int sum[N+N];	//sum[i]表示尾端点在[1,i]条件下的本质不同子串个数
int pre[128];	//pre[ch]表示字符同为ch的前一个字符的下标
int main()
{
	while (~scanf("%d%d", &n,&k))
	{
		MS(pre, -1);
		scanf("%s", s + 1);
		m = strlen(s + 1);
		sum[0] = 1;
		for (int i = 1; i <= m + n; ++i)
		{
			char ch;
			if (i <= m)ch = s[i];
			else {
				ch = 'a';
				for (char i = 'a' + 1; i < 'a' + k; ++i)if (pre[i] < pre[ch])ch = i;
			}
			//如果字符s[i]是第一次出现,那么以它为结尾,可以累加上之前所有本质不同子串
			if (pre[ch] == -1)f[i] = sum[i - 1];
			//如果字符s[i]不是第一次出现,那么以它为结尾,只可以累加上[pre[i],i-1]范围内的所有本质不同子串
			else f[i] = (sum[i - 1] - sum[pre[ch]-1] + Z) % Z;
			sum[i] = (sum[i - 1] + f[i]) % Z;
			pre[ch] = i;
		}
		printf("%d\n", sum[m + n]);
	}
	return 0;
}
/*
【trick&&吐槽】
很多题目不要总想着是自己不会的算法。
尝试用自己会的知识解决题目才是一个ACMer要具备的素质

【题意】
给你一个长度为m(1e5)的字符串。
我们还可以在这个字符串后面添加长度为n(1e5)的串,添加串的字符集为[1,26]
问你最后最多能使得这个字符串中有多少个本质不同的子串。
输出子串个数%(1e9+7)

【类型】
DP

【分析】
首先,对于前m位。
如何算本质不同字符串的个数呢?
如果字符s[i]是第一次出现,那么以它为结尾,可以累加上之前所有本质不同子串
如果字符s[i]不是第一次出现,那么以它为结尾,只可以累加上[pre[i],i-1]范围内新出现的所有本质不同子串

然而,接下来需要处理,后面要添加什么字符。
我们分析DP转移方程,发现每次加的是一个区间范围内的本质不同子串。
所以我们只要使得这个字符上一次出现的位置距离本次出现的位置尽可能远就可以啦。

【时间复杂度&&优化】
O(m+nk)

*/


你可能感兴趣的:(codeforces,题库-CF,动态规划-线性DP)