CODEFORCES 645E Intellectual Inquiry
2016-05-27 20:51
399 查看
// CODEFORCES 645E Intellectual Inquiry
http://codeforces.com/problemset/problem/645/E
字母表只有前面 k 个小写字母。给出一个字符串 s,你可以往 s 后添加 n 个字母,使得,总的字符串的不同子序列最多。
s
1 ≤ n ≤ 1,000,000
1 ≤ k ≤ 26
1 ≤ |s| ≤ 1,000,000
f[i] 表示以 i 为结尾的子序列(不含空串)有多少个,往字符串后面加一个字母 c,则只有 f[c] 会改变。而且是改成 ∑f[] + 1。重点在这个值跟 c 是没有关系的,改变之后的所以子序列数目的和是 ∑f[] - f[c] + ∑f[] + 1,要使这个值最大,应该使得 f[c] 最小,也就是说,添加一个使得 f[c] 最小的 c 在字符串末尾是最佳的方案。
* Author: +7w
*/
#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <bitset>
#include <functional>
#include <list>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
const int INF3 = 0x3f3f3f3f;
const int INF5 = 0x5f5f5f5f;
const double PI = acos(-1.0);
const double EPS9 = 1e-9;
const int TEN3 = 1000;
const int TEN6 = TEN3 * TEN3;
const int TEN9 = TEN6 * TEN3;
typedef long long llong;
typedef unsigned long long ullong;
typedef std::pair<int, int> pii;
#define FST first
#define SEC second
#define PB push_back
#define MP make_pair
#define CLEAR(a) memset(a, 0, sizeof(a))
#define FILL(a, c) memset(a, c, sizeof(a))
#define COPY(a, b) memcpy(a, b, sizeof(b))
const int MOD = TEN9 + 7;
const int N = TEN6 + 10;
const int K = 30;
const int M = TEN6 + 10;
char str[M];
pii cv
;
int main(int argc, char const *argv[])
{
int n, k;
scanf("%d %d", &n, &k);
scanf("%s", str);
for (int i = 0; i < k; ++i) {
cv[i].FST = i; // cmper
cv[i].SEC = 0; // value
}
int sum = 0;
for (int i = 0; str[i]; ++i) {
int j = str[i] - 'a';
int tmp_sec = cv[j].SEC;
cv[j].SEC = (sum + 1) % MOD;
sum = (sum - tmp_sec + MOD) % MOD;
sum = (sum + cv[j].SEC) % MOD;
cv[j].FST = i + k;
}
std::sort(cv, cv + k);
for (int i = 0; i < n; ++i) {
int j = i % k;
int tmp_sec = cv[j].SEC;
cv[j].SEC = (sum + 1) % MOD;
sum = (sum - tmp_sec + MOD) % MOD;
sum = (sum + cv[j].SEC) % MOD;
}
printf("%d\n", (sum + 1) % MOD);
return 0;
}
http://codeforces.com/problemset/problem/645/E
字母表只有前面 k 个小写字母。给出一个字符串 s,你可以往 s 后添加 n 个字母,使得,总的字符串的不同子序列最多。
Input
n ks
1 ≤ n ≤ 1,000,000
1 ≤ k ≤ 26
1 ≤ |s| ≤ 1,000,000
Output
输出答案模 1,000,000,007。Solution
看了题解才会的。f[i] 表示以 i 为结尾的子序列(不含空串)有多少个,往字符串后面加一个字母 c,则只有 f[c] 会改变。而且是改成 ∑f[] + 1。重点在这个值跟 c 是没有关系的,改变之后的所以子序列数目的和是 ∑f[] - f[c] + ∑f[] + 1,要使这个值最大,应该使得 f[c] 最小,也就是说,添加一个使得 f[c] 最小的 c 在字符串末尾是最佳的方案。
Code
/*** Author: +7w
*/
#include <assert.h>
#include <ctype.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
#include <bitset>
#include <functional>
#include <list>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
const int INF3 = 0x3f3f3f3f;
const int INF5 = 0x5f5f5f5f;
const double PI = acos(-1.0);
const double EPS9 = 1e-9;
const int TEN3 = 1000;
const int TEN6 = TEN3 * TEN3;
const int TEN9 = TEN6 * TEN3;
typedef long long llong;
typedef unsigned long long ullong;
typedef std::pair<int, int> pii;
#define FST first
#define SEC second
#define PB push_back
#define MP make_pair
#define CLEAR(a) memset(a, 0, sizeof(a))
#define FILL(a, c) memset(a, c, sizeof(a))
#define COPY(a, b) memcpy(a, b, sizeof(b))
const int MOD = TEN9 + 7;
const int N = TEN6 + 10;
const int K = 30;
const int M = TEN6 + 10;
char str[M];
pii cv
;
int main(int argc, char const *argv[])
{
int n, k;
scanf("%d %d", &n, &k);
scanf("%s", str);
for (int i = 0; i < k; ++i) {
cv[i].FST = i; // cmper
cv[i].SEC = 0; // value
}
int sum = 0;
for (int i = 0; str[i]; ++i) {
int j = str[i] - 'a';
int tmp_sec = cv[j].SEC;
cv[j].SEC = (sum + 1) % MOD;
sum = (sum - tmp_sec + MOD) % MOD;
sum = (sum + cv[j].SEC) % MOD;
cv[j].FST = i + k;
}
std::sort(cv, cv + k);
for (int i = 0; i < n; ++i) {
int j = i % k;
int tmp_sec = cv[j].SEC;
cv[j].SEC = (sum + 1) % MOD;
sum = (sum - tmp_sec + MOD) % MOD;
sum = (sum + cv[j].SEC) % MOD;
}
printf("%d\n", (sum + 1) % MOD);
return 0;
}
相关文章推荐
- POJ 2818 Building Block (并查集)(寻找一个元素下面有多少个元素)
- 椭圆人头跟踪bmp图像序列 BMP Image Sequences for Elliptical Head Tracking
- 椭圆人头跟踪bmp图像序列 BMP Image Sequences for Elliptical Head Tracking
- UIView动画实现
- PAT-甲级-1017. Queueing at Bank【模拟】
- UITabelView分组样式时如何调整组之间的间距
- poj1458——Common Subsequence(最长公共子序列)
- 前台模块化RequireJS+anjularJS的实战应用(二)---- 实践应用
- 重构SkinUI代码更新啦!
- Java设计模式(五):建造者模式Builder
- 获取窗口当前显示的控制器
- Xcode多种Build Configuration配置使用
- 取消UICollectionView的隐式动画
- UITableViewCell单元格设置为不可点击
- 怎么去掉Xcode工程中的某种类型的警告
- 在xib里,拖一个UIView到UITableView中作为tableFooterView
- iOS UICollectionView 高级用法(长按cell移动重新排列)
- 多线程之消费者生产者模式加入阻塞队列
- 1.2.21 Map.values方法——获取Map集合中的所有键值对象
- Codeforces Round #257 (Div. 2) B. Jzzhu and Sequences