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自动机习题的主要内容,如果未能解决你的问题,请参考以下文章

POJ2778DNA Sequence(AC自动机)

HDU3247 Resource Archiver(AC自动机+BFS+DP)

POJ3691DNA repair(AC自动机,DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

AC自动机复习

Codeforces 86C Genetic engineering(AC自动机+DP)