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

编程入门 行业动态 更新时间:2024-10-18 12:33:44
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 0001 ≤ 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".

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)

*/


更多推荐

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

本文发布于:2023-06-13 07:51:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1359227.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字符串   长度为   个数   本质   Elimination

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!