字符串题目总结

cmdoi2019 口头禅

广义后缀自动机串定位

#include<bits/stdc++.h>
using namespace std;
const int L=3e5+5;
struct yuansu {
	int ch[26];
	int len,fa,self_ch,val;
	yuansu() {
		memset(ch,0,sizeof(ch));
		len=fa=self_ch=val;
	}
} dian[2*L],trie[L];
int cnt=0,lenth,now,head(0),tail(1),q[L],n,lst=1,trie_id_to_SAM_id[L],st[L][21],m,w[L],index_to_trie_id[L];
long long int ans;
string S,T;
void init() {
	cin>>n>>m;
	cin>>S;
	cin>>T;
	for(int i=1; i<=n; i++)cin>>w[i];
	for(int i=n; i>=1; i--)w[i]+=w[i+1];
	now=0;
	lenth=n;
	for(int j=0; j<n; j++) {
		if(!trie[now].ch[S[j]-'a']) {
			trie[now].ch[S[j]-'a']=++cnt;
			trie[trie[now].ch[S[j]-'a']].self_ch=S[j]-'a';
			trie[trie[now].ch[S[j]-'a']].fa=now;
			trie[trie[now].ch[S[j]-'a']].len=trie[now].len+1;
		}
		now=trie[now].ch[S[j]-'a'];
		trie[now].val=w[j+1];
	}
	now=0;
	lenth=n;
	for(int j=0; j<n; j++) {
		if(!trie[now].ch[T[j]-'a']) {
			trie[now].ch[T[j]-'a']=++cnt;
			trie[trie[now].ch[T[j]-'a']].self_ch=T[j]-'a';
			trie[trie[now].ch[T[j]-'a']].fa=now;
			trie[trie[now].ch[T[j]-'a']].len=trie[now].len+1;
		}
		now=trie[now].ch[T[j]-'a'];
		index_to_trie_id[j+1]=now;
	}
	return;
}
void bfs_trie() {
	q[0]=0;
	while(head!=tail) {
		for(int i=0; i<=25; i++) {
			if(trie[q[head]].ch[i]) {
				q[tail++]=trie[q[head]].ch[i];
			}
		}
		++head;
	}
	return;
}
void insert(int cha,int nw,int v) {
	int np=++cnt,p=lst;
	trie_id_to_SAM_id[nw]=np;
	dian[np].val=v;
	dian[np].len=dian[p].len+1;
	for(; p&&!dian[p].ch[cha]; p=dian[p].fa)dian[p].ch[cha]=np;
	if(!p) {
		dian[np].fa=1;
	} else {
		int q=dian[p].ch[cha];
		if(dian[q].len==dian[p].len+1) {
			dian[np].fa=q;
		} else {
			int nq=++cnt;
			dian[nq]=dian[q];
			dian[nq].len=dian[p].len+1;
			dian[q].fa=dian[np].fa=nq;
			for(; p&&dian[p].ch[cha]==q; p=dian[p].fa)dian[p].ch[cha]=nq;
		}
	}
	return;
}
void build_SAM() {
	cnt=1;
	tail--;
	trie_id_to_SAM_id[0]=1;
	for(int i=1; i<=tail; i++) {
		lst=trie_id_to_SAM_id[trie[q[i]].fa];
		insert(trie[q[i]].self_ch,q[i],trie[q[i]].val);
	}
	return;
}
struct item {
	int nx,to;
	item() {
		nx=to=0;
	}
} bian[L];
int ls[L],cnt_tree;
void add(int x,int y) {
	bian[++cnt_tree].nx=ls[x];
	bian[cnt_tree].to=y;
	ls[x]=cnt_tree;
}
void dfs(int now,int fa) {
	for(int i=ls[now]; i; i=bian[i].nx) {
		if(bian[i].to!=fa) {
			dfs(bian[i].to,now);
			dian[now].val+=dian[bian[i].to].val;
		}
	}
	return;
}
int main() {
	init();
	bfs_trie();
	build_SAM();
	for(int i=1; i<=cnt; i++)add(dian[i].fa,i),add(i,dian[i].fa); 
	dfs(0,-1);
	for(int i=1; i<=cnt; i++)st[0][i]=dian[i].fa;
	for(int i=1; i<=20; i++) {
		for(int j=1; j<=cnt; j++) {
			st[i][j]=st[i-1][st[i-1][j]];
		}
	}
	for(int i=1; i<=m; i++) {
		int l,r;
		cin>>l>>r;
		int now(trie_id_to_SAM_id[index_to_trie_id[r]]);
		for(int j=20; j>=0; j--) {
			if(dian[st[j][now]].len>=r-l+1)now=st[j][now];
		}
		cout<<dian[now].val<<'\n';
	}
	return 0;
}
/*
1
ab
*/

posted @ 2023-07-12 17:10  永无岛  阅读(10)  评论(0编辑  收藏  举报