D. Tavas and Malekas DFS模拟 + kmp + hash || kmp + hash
生活随笔
收集整理的這篇文章主要介紹了
D. Tavas and Malekas DFS模拟 + kmp + hash || kmp + hash
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://codeforces.com/contest/535/problem/D
如果真的要把m個串覆蓋上一個串上面,是可以得,不會超時。
要注意到一點,全部覆蓋后再判斷時候合法,和邊放邊判斷,結果是一樣的,后者還更難做到。
那么就是先按順序把串覆蓋上去,已經存在的就不去覆蓋了,然后kmp一次記錄匹配位置,判斷即可。
用DFS覆蓋,DFS回溯的時候記錄一個數組tonext[i]表示第i個點的第一個空位是tonext[i],這樣覆蓋上去就是O(n)
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
int tonext[maxn];
int ret;
char str[maxn];
char sub[maxn];
void dfs(int cur, int k, int from) {
if (k < ) return;
if (k == ) {
ret = cur;
return;
}
if (tonext[cur] != cur) {
ret = tonext[cur];
dfs(tonext[cur], k - (tonext[cur] - cur), from + tonext[cur] - cur);
tonext[cur] = ret;
} else {
ret = cur + ;
str[cur] = sub[from];
dfs(cur + , k - , from + );
tonext[cur] = ret;
}
}
int a[maxn];
bool HASH[maxn];
int kmpnext[maxn];
void get_next(char sub[], int lensub) {
int i = , j = ;
kmpnext[] = ;
while (i <= lensub) {
if (j == || sub[i] == sub[j]) {
kmpnext[++i] = ++j;
} else j = kmpnext[j];
}
return;
}
void kmp(int lenstr, int lensub) {
int i = , j = ;
while (i <= lenstr) {
if (j == || str[i] == sub[j]) {
++i;
++j;
} else j = kmpnext[j];
if (j == lensub + ) {
HASH[i - lensub] = true;
j = kmpnext[j];
}
}
return;
}
void work() {
int lenstr, m;
scanf("%d%d", &lenstr, &m);
for (int i = ; i <= lenstr; ++i) {
tonext[i] = i;
str[i] = 'A';
// printf("f");
}
// printf("%c\n", str[1]);
scanf("%s", sub + );
int lensub = strlen(sub + );
for (int i = ; i <= m; ++i) {
scanf("%d", &a[i]);
dfs(a[i], lensub, );
}
str[lenstr + ] = '\0';
// printf("%s\n", str + 1);
get_next(sub, lensub);
kmp(lenstr, lensub);
for (int i = ; i <= m; ++i) {
if (!HASH[a[i]]) {
cout << << endl;
return;
}
}
LL ans = ;
for (int i = ; i <= lenstr; ++i) {
if (str[i] == 'A') {
ans *= ;
if (ans >= MOD) ans %= MOD;
}
}
cout << ans << endl;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
開始的時候想不到直接kmp
用的其實就是kmp的next數組,不斷next[next[]]
就是記錄所有的前綴和后綴相等。
對于abc****abc,也就是前后綴相等的話,長度是3
記上一個覆蓋到的位置是pos[i - 1] + lensub - 1
然后如果這個和他沒交集,就算,如果有,要判斷。怎么判斷呢?
算出交集大小,如果交集剛好是3,那么是可以得。否則,是NO
交集是3說明后綴的那3個和前綴匹配了。
注意m可能是0
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e6 + ;
const int MOD = 1e9 + ;
char sub[maxn];
int tonext[maxn];
int pos[maxn];
bool book[maxn];
void get_next(char sub[], int lensub) {
int i = , j = ;
tonext[] = ;
while (i <= lensub) {
if (j == || sub[i] == sub[j]) {
tonext[++i] = ++j;
} else j = tonext[j];
}
return;
}
void work() {
int lenstr, m;
// cin >> lenstr >> m;
// cin >> sub + 1;
scanf("%d%d", &lenstr, &m);
scanf("%s", sub + );
int lensub = strlen(sub + );
get_next(sub, lensub);
for (int i = ; i <= m; ++i) {
// cin >> pos[i];
scanf("%d", &pos[i]);
}
int t = tonext[lensub + ];
while (t != ) {
book[t - ] = true;
t = tonext[t];
}
int total = lenstr - lensub;
if (m == ) {
total += lensub;
}
for (int i = ; i <= m; ++i) {
int to = pos[i - ] + lensub - ;
int haha = to - pos[i] + ;
if (haha <= ) {
total -= lensub;
continue;
}
if (!book[haha]) {
printf("0\n");
return;
}
total -= lensub - haha;
}
LL ans = ;
for (int i = ; i <= total; ++i) {
ans *= ;
if (ans >= MOD) ans %= MOD;
}
printf("%I64d\n", ans);
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}
總結
以上是生活随笔為你收集整理的D. Tavas and Malekas DFS模拟 + kmp + hash || kmp + hash的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 17-7-26-react-router
- 下一篇: UCOS 杂项 笔记