AC自动机习题
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AC自动机习题相关的知识,希望对你有一定的参考价值。
AC自动机习题
P2414 [NOI2011] 阿狸的打字机
看jiangly 巨巨的题解即可。
// Problem: P2322 [HNOI2006]最短母串问题
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2322
// Memory Limit: 32 MB
// Time Limit: 1000 ms
// Date: 2021-12-02 21:47:26
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5,M=N*(1<<12)+1,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
int len;
vector<PII>q[N];
int res[N];
int Q;
struct BIT
#define lowbit(x) x&(-x)
#define il inline
ll s[N];
int n;
il void upd(int x,int v)
while(x<=n)
s[x]+=v;x+=lowbit(x);
return;
il ll que(int x)
ll ans=0;
while(x)
ans+=s[x];x-=lowbit(x);
return ans;
B;
char s[N];
struct ACAM
#define il inline
int son[N][26],fa[N],id;
int pre[N],a[N],n;
struct edge
int to,nt;
e[N<<1];
int cnt,h[N];
void add(int u,int v)
e[++cnt]=v,h[u],h[u]=cnt;
e[++cnt]=u,h[v],h[v]=cnt;
il void init()
id=0;
mst(fa,0);
mst(son,0);
mst(pre,0);
il void ins(char *s)
int rt = 0; len =strlen(s);
for(int i=0;i<len;++i)
char ch = s[i];
if(ch>='a'&&ch<='z')
int j = ch - 'a';
if(!son[rt][j]) son[rt][j]=++id,pre[id] = rt;
rt = son[rt][j];
else if(ch=='P')
a[++n] = rt;
else if(ch=='B') rt = pre[rt];
int in[N],out[N],dfn;
void dfs(int u,int f)
in[u]=++dfn;
for(int i=h[u];i;i=e[i].nt)
int v=e[i].to;
if(v^f) dfs(v,u);
out[u] = dfn;
il void getFail()
queue<int>q;
for(int i=0;i<26;i++)
if(son[0][i]) fa[son[0][i]]=0,q.push(son[0][i]);
while(!q.empty())
int u=q.front();q.pop();
//printf("u=%d\\n",u);
for(int i=0;i<26;i++)
if(son[u][i])
fa[son[u][i]] = son[fa[u]][i];
q.push(son[u][i]);
else son[u][i] = son[fa[u]][i];
rep(i,1,id)
add(i,fa[i]);
dfs(0,0);
//printf("len=%d dfn=%d\\n",len,dfn);
void solve()
B.n = dfn;
//printf("len=%d\\n",len);
for(int i = 0,idx=0,rt = 0; i<len ;i++)
char ch = s[i];
if(ch>='a'&&ch<='z')
rt = son[rt][ch-'a'];
B.upd(in[rt],1);
else if(ch=='P')
++idx;
for(int j=0;j<SZ(q[idx]);j++)
int x = q[idx][j].x, index = q[idx][j].y;
res[index] = B.que(out[a[x]]) - B.que(in[a[x]]-1);
else if(ch=='B')
B.upd(in[rt],-1);
rt = pre[rt];
rep(i,1,Q) printf("%d\\n",res[i]);
T;
int main()
scanf("%s",s);T.ins(s);T.getFail();
scanf("%d",&Q);
rep(i,1,Q)
int x,y;scanf("%d%d",&x,&y);
q[y].pb(x,i);
T.solve();
return 0;
P3041 [USACO12JAN]Video Game G
AC自动机+dp
构建fail指针时,维护一个val 贡献,要加上子树。
然后就dp就可以了。
// Problem: P3041 [USACO12JAN]Video Game G
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3041
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-12-03 15:01:41
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=305,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = 402653189,805306457,1610612741,998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n)
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
template <typename T> //x=max(x,y) x=min(x,y)
void cmx(T &x,T y)
if(x<y) x=y;
template <typename T>
void cmn(T &x,T y)
if(x>y) x=y;
int n,K;
struct ACAM
#define il inline
int son[N][26],fa[N],id,val[N];
il void init()
id=0;
mst(fa,0);
mst(son,0);
il void ins(char *s)
int rt = 0, n =strlen(s);
for(int i=0;i<n;++i)
int j=s[i]-'A';
if(!son[rt][j]) son[rt][j]=++id;
rt = son[rt][j];
val[rt]++;
il void getFail()
queue<int>q;
for(int i=0;i<3;i++)
if(son[0][i]) fa[son[0][i]]=0,q.push(son[0][i]);
while(!q.empty())
int u=q.front();q.pop();
//printf("u=%d\\n",u);
for(int i=0;i<3;i++)
if(son[u][i])
fa[son[u][i]] = son[fa[u]][i];
q.push(son[u][i]);
else son[u][i] = son[fa[u]][i];
val[u] += val[fa[u]];
int f[1005][N];
il void solve()
rep(i,0,K)
rep(j,1,id)
f[i][j] = -inf;
rep(i,1,K)
rep(j,0,id)
rep(k,0,3)
f[i][son[j]以上是关于AC自动机习题的主要内容,如果未能解决你的问题,请参考以下文章
HDU3247 Resource Archiver(AC自动机+BFS+DP)