题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430
WA:
1.每个串只记一次,不要记多次
2.忽略等号不转码直接跑AC自动机会错,例子:
转码前:
1
aGVs
1
aGhlbA==ans = 0
--------------
转码后:
1
hel
1
hhelans = 1
3.char 可储存的范围是-128~127,转码得到的范围是0~255,不能用char存
4.其余未知情况只能友情给出2组随机小数据
Input1:
5
YQ==
YWE=
YWFh
YWFhYQ==
YWFhYWE=
1
YWFhYQ==
Output1:
4
Input2:
3
KCgoKSkp
JiYmJSUl
JSsrLy8=
1
KCgoKSkpKSYmJiYlJSUrKy8v
Output2:
3
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define for1(i,a,b) for (int i=a;i<=b;i++)
#define for0(i,a,b) for (int i=a;i<b;i++)
#define rof1(i,a,b) for (int i=a;i>=b;i--)
#define rof0(i,a,b) for (int i=a;i>b;i--)
#define pb push_back
#define fi first
#define se second
#define debug(x) printf("----Line %s----\n",#x)
#define pt(x,y) printf("%s = %d\n",#x,y)
#define INF 0x3f3f3f3f
#define df(x) ll x;scanf("%I64d",&x)
#define df2(x,y) ll x,y;scanf("%I64d %I64d",&x,&y)
#define mod 1000000007
#define duozu(T) int T;scanf("%d",&T);while (T--)
const int N = 3000;
const int maxnode = 88*512 + 100;
const int ALP = 256;
int trie[maxnode][ALP],sz;
int fail[maxnode],last[maxnode];
int val[maxnode];
char ss[N];
int s[N];
bool vis[520];
void init(int x)
{
memset(trie[x],0,sizeof trie[x]);
val[x] = 0;
}
int idx(char ch)
{
if (ch>='A' && ch<='Z') return ch-'A';
else if (ch>='a' && ch<='z') return ch-'a'+26;
else if (ch>='0' && ch<='9') return ch-'0'+52;
else if (ch=='+') return 62;
else if (ch=='/') return 63;
else return 0;
}
void insert(int s[],int id)
{
int u = 0;
for (int i=0;~s[i];i++){
int c = s[i];
if (!trie[u][c]){
init(sz);
trie[u][c] = sz++;
}
u = trie[u][c];
}
val[u] = id;
}
queue<int>que;
void buildAC()
{
for0(c,0,ALP){
int v = trie[0][c];
if (v){que.push(v);
fail[v] = 0;
last[v] = 0;
}
}
while (!que.empty()){
int u = que.front();que.pop();
for0(c,0,ALP){
int v = trie[u][c];
if (!v){
trie[u][c] = trie[fail[u]][c];
continue;
}
int fa = fail[u];
while (fa && !trie[fa][c]) fa = fail[fa];
fail[v] = trie[fa][c];
last[v] = val[fail[v]]? fail[v]:last[fail[v]];
que.push(v);
}
}
}
void cal(int x)
{
while(x){
vis[val[x]] = true;
x = last[x];
}
}
void FIND(int s[])
{
int u = 0;
for (int i=0;~s[i];i++){
int c = s[i];
u = trie[u][c];
if (val[u]) cal(u);
else if (last[u]) cal(last[u]);
}
}
int main()
{
int n;
//freopen("C:/Users/DELL/Desktop/input.txt", "r", stdin);
//freopen("C:/Users/DELL/Desktop/output.txt", "w", stdout);
while (~scanf("%d",&n)){
sz = 1;
init(0);
int id = 1;
while (n--){
scanf("%s",ss);
int cnt = 0;
int len = strlen(ss);
if (ss[len-1]=='=')ss[len-1] = 0,cnt = 1;
if (ss[len-2]=='=')ss[len-2] = 0,cnt = 2;
int tot = 0;
for (int i=0;i<len;i+=4){
s[tot++] = ((idx(ss[i])<<2) + (idx(ss[i+1])>>4) )&255;
s[tot++] = ((idx(ss[i+1])<<4) + (idx(ss[i+2])>>2) )&255;
s[tot++] = ((idx(ss[i+2])<<6) + (idx(ss[i+3])) )&255;
}
tot-=cnt;
s[tot] = -1;
//cout << "after trans:";for (int i=0;i<tot;i++) putchar(s[i]);putchar('\n');
insert(s,id++);
}
buildAC();
scanf("%d",&n);
while (n--){
scanf("%s",ss);
int cnt = 0;
int len = strlen(ss);
if (ss[len-1]=='=')ss[len-1] = 0,cnt = 1;
if (ss[len-2]=='=')ss[len-2] = 0,cnt = 2;
int tot = 0;
for (int i=0;i<len;i+=4){
s[tot++] = ((idx(ss[i])<<2) + (idx(ss[i+1])>>4) )&255;
s[tot++] = ((idx(ss[i+1])<<4) + (idx(ss[i+2])>>2) )&255;
s[tot++] = ((idx(ss[i+2])<<6) + (idx(ss[i+3])) )&255;
}
tot-=cnt;
s[tot] = -1;
memset(vis,false,sizeof vis);
//cout << "after trans:";for (int i=0;i<tot;i++) putchar(s[i]);putchar('\n');
FIND(s);
int ans = 0;
for0(i,1,520) ans += vis[i];
printf("%d\n",ans);
}
printf("\n");
}
return 0;
}
总结:
1.char128就越界了,记住!(以前固有印象是0~255...)