补上
HDU3065:多组数据有点坑爹
HDU2222:模板,但是换了一种写法,虽然之前那种写法貌似复杂度也是O(N)的(不知道怎么证明,但是感觉和KMP差不多).这种写法构建了一个trie图,复杂度是很显然的O(N)而且代码还短一点,大概要快十分之一。
代码如下:
HDU3065:
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using namespace std;
#define MAX_SIZE 2000005
#define INF 0x3F3F3F3F
#define Eps
#define Mod
inline int Get_Int()
{
int Num = 0, Flag = 1;
char ch;
do
{
ch = getchar();
if(ch == '-')
Flag *= -1;
}
while(ch < '0' || ch > '9');
do
{
Num = Num * 10 + ch - '0';
ch = getchar();
}
while(ch >= '0' && ch <= '9');
return Num * Flag;
}
class Node
{
public:
Node *Fail, *Next[26];
int Count;
}*Root, *Empty;
int N, Length;
int Num[1005];
char Str[MAX_SIZE], Virus[1005][55];
inline Node* New()
{
Node *x = (Node*)(malloc(sizeof(Node)));
memset(x, 0, sizeof(Node));
return x;
}
inline void Build_Trie()
{
Root = New();
for(int i = 1; i <= N; ++i)
{
scanf("%s", Virus[i]);
Node *temp = Root;
for(int j = 0, Length = strlen(Virus[i]), To; j < Length; ++j, temp = temp -> Next[To])
{
To = Virus[i][j] - 'A';
if(!temp -> Next[To])
temp -> Next[To] = New();
}
temp -> Count = i;
}
}
inline void Build_ACAM()
{
queue<Node*> Queue;
Queue.push(Root);
Empty = New();
for(int i = 0; i < 26; ++i)
Empty -> Next[i] = Root;
Root -> Fail = Empty;
while(!Queue.empty())
{
Node *Now = Queue.front(), *temp;
Queue.pop();
for(int i = 0 ; i < 26; ++i)
if(Now -> Next[i])
{
for(temp = Now -> Fail; !temp -> Next[i]; temp = temp -> Fail);
Now -> Next[i] -> Fail = temp -> Next[i];
Queue.push(Now -> Next[i]);
}
}
}
inline void Solve()
{
Node* Now = Root;
for(int i = 0; i < Length; ++i)
{
if(Str[i] < 'A' || Str[i] > 'Z')
{
Now = Root;
continue;
}
int To = Str[i] - 'A';
while(!Now -> Next[To])
Now = Now -> Fail;
Now = Now -> Next[To];
for(Node *temp = Now; temp != Root; temp = temp -> Fail)
++Num[temp -> Count];
}
for(int i = 1; i <= N; ++i)
if(Num[i])
printf("%s: %d\n", Virus[i], Num[i]);
}
inline void Release(Node *Now)
{
for(int i = 0; i < 26; ++i)
if(Now -> Next[i])
Release(Now -> Next[i]);
free(Now);
}
int main()
{
while(cin >> N)
{
Build_Trie();
Build_ACAM();
scanf("%s", Str);
Length = strlen(Str);
Solve();
Release(Root);
free(Empty);
memset(Num, 0, sizeof(Num));
}
return 0;
}
HDU2222:
#include "cstdio"
#include "cstdlib"
#include "iostream"
#include "algorithm"
#include "cstring"
#include "queue"
using namespace std;
#define MAX_SIZE 10005
#define INF 0x3F3F3F3F
#define Eps
#define Mod
inline int Get_Int()
{
int Num = 0, Flag = 1;
char ch;
do
{
ch = getchar();
if(ch == '-')
Flag *= -1;
}
while(ch < '0' || ch > '9');
do
{
Num = Num * 10 + ch - '0';
ch = getchar();
}
while(ch >= '0' && ch <= '9');
return Num * Flag;
}
class Node
{
public:
Node *Next[26], *Fail;
int Count;
}*Root, *Empty;
int Length[MAX_SIZE];
int M, N, T, Ans;
char Words[MAX_SIZE][55], Str[1000005];
inline Node* New()
{
Node *x = (Node*)(malloc(sizeof(Node)));
memset(x, 0, sizeof(Node));
return x;
}
inline void Build_Trie()
{
Root = New();
for(int i = 1; i <= N; ++i)
{
Node *temp = Root;
for(int j = 0, To; j < Length[i]; ++j, temp = temp -> Next[To])
{
To = Words[i][j];
if(!temp -> Next[To])
temp -> Next[To] = New();
}
temp -> Count++;
}
}
inline void Build_ACAM()
{
queue<Node*> Queue;
Queue.push(Root);
Empty = New();
for(int i = 0; i < 26; ++i)
Empty -> Next[i] = Root;
Root -> Fail = Empty;
while(!Queue.empty())
{
Node *Now = Queue.front();
Queue.pop();
for(int i = 0; i < 26; ++i)
if(Now -> Next[i])
{
Now -> Next[i] -> Fail = Now -> Fail -> Next[i];
Queue.push(Now -> Next[i]);
}
else
Now -> Next[i] = Now -> Fail -> Next[i];
}
}
inline void Solve()
{
Node *Now = Root;
Ans = 0;
for(int i = 0; i < M; ++i)
{
int To = Str[i];
Now = Now -> Next[To];
for(Node* temp = Now; temp != Root; temp = temp -> Fail)
{
Ans += temp -> Count;
temp -> Count = 0;
}
}
}
int main()
{
cin >> T;
while(T--)
{
N = Get_Int();
for(int i = 1; i <= N; ++i)
{
scanf("%s", Words[i]);
Length[i] = strlen(Words[i]);
for(int j = 0; j < Length[i]; ++j)
Words[i][j] -= 'a';
}
Build_Trie();
Build_ACAM();
scanf("%s", Str);
M = strlen(Str);
for(int i = 0; i < M; ++i)
Str[i] -= 'a';
Solve();
printf("%d\n", Ans);
}
return 0;
}