醉了,看个ac自动机的模板,,照着别人的敲都敲不对。
还是看kuangbin大神的吧。。。
http://www.cnblogs.com/kuangbin/p/3164106.html
参看J
这种找源代码。。我还是用博客的巴,尽量不要照着敲。要不然没得复制就不知道怎么班。。
病毒侵袭模板。。。
struct Trie
{
int next[N][128],fail[N],end[N];
int root,L;
int newnode() {
for(int i = 0;i < 128;i++)
next[L][i] = -1;
end[L++] = -1;
return L-1;
}
void init() {
L = 0;
root = newnode();
}
void insert(char s[],int id) {
int len = strlen(s);
int now = root;
for(int i = 0;i < len;i++) {
if(next[now][s[i]] == -1)
next[now][s[i]] = newnode();
now=next[now][s[i]];
}
end[now]=id;
}
void build() {
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 128;i++)
if(next[root][i] == -1)
next[root][i] = root;
else {
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty()) {
int now = Q.front();
Q.pop();
for(int i = 0;i < 128;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
bool used[510];
bool query(char buf[],int n,int id) {
int len = strlen(buf);
int now = root;
memset(used,false,sizeof(used));
bool flag = false;
for(int i = 0;i < len;i++)
{
now = next[now][buf[i]];
for(int temp=now;temp!=root;temp=fail[temp]){
if(end[temp]!=-1){
used[end[temp]]=true;
flag=true;
}
}
}
if(!flag)return false;
printf("web %d:",id);
for(int i = 1;i <= n;i++)
if(used[i])
printf(" %d",i);
printf("\n");
return true;
}
}ac;
然后终于把那个最入门的模板提做了。。。
感觉好多坑。。
https://vjudge.net/contest/172503#problem/C
和上题差不多。。
但是我的想法比较复杂。。然后又看题解了。。发现题解直接用终止节点就记录id。然后枚举就顺序输出叻。
然后自己忘了build。。。。查了挺久的。。
然后别人的没有去掉不是大写字母的。。分支128 。。
https://vjudge.net/contest/172503#problem/H
看kuangbin大神的。。原来可以这样加个数组判断不可以重复的情况
他这里对于每一个单词的深度deep都有记录。。。感觉是挺难想的。。
https://vjudge.net/contest/172503#problem/G
第一道ac自动机+dp的题目,对于他这种按照自动机上有没有指针的方式来判断可不可dp的方式自己确实没有见过。。
感觉这个dp做了之后对ac自动机的模式比较了解了。。注意什么地方要改。。
参考http://blog.csdn.net/human_ck/article/details/6577142
#include<algorithm>
#include<vector>
#include<cstring>
#include<string>
#include<iomanip>
#include<cstdio>
#include<stack>
#include<iostream>
#include<map>
#include<queue>
using namespace std;
#define sf scanf
#define pf printf
#define mem(a,b) memset(a,b,sizeof(a));
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define bug1 puts("bug1");
#define bug2 puts("bug2");
#define bug3 puts("bug3");
#define N 26*55
#define M 200
#define ULL unsigned long long
#define LL long long
const int INF=1e9;
const int inf=0x3f3f3f3f;
//2017年07月30日20:44:28
int len;
int dp[1010][20*26];
char s[1010];
inline int getcode(char c){
if(c=='A')return 0;
if(c=='G')return 1;
if(c=='C')return 2;
if(c=='T')return 3;
}
struct Trie
{
int next[N][4],fail[N],end[N];
int root,L;
int newnode() {
for(int i = 0;i < 4;i++)
next[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init() {
L = 0;
root = newnode();
}
void insert(char s[]) {
int len = strlen(s);
int now = root;
for(int i = 0;i < len;i++) {
int index=getcode(s[i]);
if(next[now][index] == -1)
next[now][index] = newnode();
now=next[now][index];
}
end[now]=1;
}
void build() {
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 4;i++)
if(next[root][i] == -1)
next[root][i] = root;
else {
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty()) {
int now = Q.front();
Q.pop();
for(int i = 0;i < 4;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]] = next[fail[now]][i];//这个地方注意为什么要这样改。
if(end[fail[next[now][i]]])end[next[now][i]]=1;
Q.push(next[now][i]);
}
}
}
int solve(){
int tot=L-1;
for(int i=0;i<=len;++i){
for(int j=0;j<=tot;++j){
dp[i][j]=inf;
}
}
dp[0][0]=0;
for(int i=1;i<=len;++i){
for(int j=0;j<=tot;++j){
if(dp[i-1][j]<inf){
for(int k=0;k<4;++k){
if(end[next[j][k]]==0){
dp[i][next[j][k]]=min(dp[i][next[j][k]],dp[i-1][j]+(getcode(s[i])!=k));
}
}
}
}
}
int ans=inf;
for(int i=0;i<=tot;++i){
if(dp[len][i]<ans&&end[i]==0)
ans=dp[len][i];
}
if(ans==inf)return -1;
return ans;
}
}ac;
int main(){
int n;int cas=0;
while(~sf("%d",&n)&&n!=0){
mem(dp,inf);
ac.init();
rep(i,1,n){
char t[22];sf("%s",t);ac.insert(t);
}
ac.build();
sf("%s",s+1);
len=strlen(s+1);
int ret=ac.solve();
if(ret==-1)pf("Case %d: -1\n",++cas);
else pf("Case %d: %d\n",++cas,ret);
}
}
https://vjudge.net/contest/172503#problem/S
字符串hash。。 不过这是很初级的了。。。/
https://vjudge.net/contest/172503#problem/D
这题还没看懂。。因为对于矩阵快速幂不熟,而且不知道为什么要这样。。。