T 1 : 病 毒 侵 袭 T1:病毒侵袭 T1:病毒侵袭
A C C o d e \mathrm{AC \ Code} AC Code
#include<bits/stdc++.h>
#define maxn 100005
#define maxc 95
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
using namespace std;
int total;
namespace AC{
int tr[maxn][maxc],fa[maxn],tot;
set<int>ed[maxn];
void clr(){
for(;tot;) memset(tr[tot],0,sizeof tr[tot]),ed[tot].clear(),fa[tot--]=0;
}
void ins(char *s,int n,int id){
int u=0,v;
rep(i,0,n-1) (!tr[u][v=s[i]-32])&&(tr[u][v]=++tot),u=tr[u][v];
ed[u].insert(id);
}
void Build(){
static int q[maxn],L,R;
rep(i,L=R=0,maxc-1) if(tr[0][i]) q[R++]=tr[0][i];
for(int u;L<R;){
u=q[L++];
if(ed[fa[u]].size() <= 3)
ed[u].insert(ed[fa[u]].begin(),ed[fa[u]].end());
rep(i,0,maxc-1)
if(tr[u][i])
q[R++]=tr[u][i],fa[tr[u][i]]=tr[fa[u]][i];
else
tr[u][i] = tr[fa[u]][i];
}
}
void qry(char *s,int n,int id){
int u=0,v;
set<int>r;
rep(i,0,n-1)
u=tr[u][v=s[i]-32],
r.insert(ed[u].begin(),ed[u].end());
if(r.size()){
total++;
printf("web %d:",id);
for(set<int>::iterator it=r.begin();it!=r.end();it++)
printf(" %d",*it);
putchar('\n');
}
}
}
int main(){
int n;scanf("%d",&n);
rep(i,1,n){
static char s[205];
scanf("%s",s);
int m = strlen(s);
AC::ins(s,m,i);
}
AC::Build();
scanf("%d",&n);
rep(i,1,n){
static char s[10005];
scanf("%s",s);
int m = strlen(s);
AC::qry(s,m,i);
}
printf("total: %d\n",total);
}
T 2 考 研 路 茫 茫 — — 单 词 情 结 \mathrm{T2 考研路茫茫——单词情结 } T2考研路茫茫——单词情结
A C C o d e \mathrm{AC \ Code} AC Code
#include<bits/stdc++.h>
#define maxn 27
#define maxc 26
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define Ct const
#define LL unsigned long long
using namespace std;
int N;
struct mat{
LL a[maxn][maxn];
mat(LL d=0){
memset(a,0,sizeof a);rep(i,0,maxn-1) a[i][i]=d; }
mat operator *(Ct mat &B)Ct{
mat r;
rep(i,0,N-1) rep(j,0,N-1) if(a[i][j]) rep(k,0,N-1) if(B.a[j][k])
r.a[i][k] += a[i][j] * B.a[j][k];
return r;
}
}A;
mat Pow(mat b,LL k){
mat r(1);
for(;k;k>>=1,b=b*b)
if(k&1)
r=b*r;
return r;
}
namespace AC{
int tr[maxn][maxc],fa[maxn],sz;
bool tag[maxn];
void clr(){
for(;~sz;) memset(tr[sz],0,sizeof tr[sz]),tag[sz]=0,fa[sz--]=0;
sz=0;
}
void ins(char *s,int n){
int u=0,v;
rep(i,0,n-1) (!tr[u][v=s[i]-'a'])&&(tr[u][v]=++sz),u=tr[u][v];
tag[u]=1;
}
void Build(){
static int q[maxn],L,R;
rep(i,L=R=0,maxc-1) if(tr[0][i]) q[R++]=tr[0][i];
for(int u;L<R;){
u=q[L++];
tag[u] |= tag[fa[u]];
rep(i,0,maxc-1)
if(tr[u][i])
fa[tr[u][i]]=tr[fa[u]][i],q[R++]=tr[u][i];
else
tr[u][i] = tr[fa[u]][i];
}
N = sz+2;
rep(i,0,sz) if(!tag[i])
rep(j,0,maxc-1) if(!tag[tr[i][j]])
A.a[i][tr[i][j]]++;
rep(i,0,N-1)
A.a[i][N-1]++;
}
}
LL cal(int L){
LL a=1,b=26,ra=1,rb=26;
for(;L;L>>=1,a=a+a*b,b*=b)
if(L&1)
ra=ra+a*rb,rb*=b;
return ra;
}
int main(){
int n,L;
while(~scanf("%d%d",&n,&L)){
AC::clr();A=mat(0);
for(;n--;){
static char s[6];
scanf