Mr. [TJOI2019] toluene Luo Gu P5341 and large center string [SAM]

Portal
get after a string, it first established the SAM, and then each node statistics \ (endpos \) values, that is, the number of sub-strings each node represents occurring, if the \ (endpos [x] = k \) , so long as \ (len [fa [x] ] + 1, ..., len [x] \) substring are legitimate, plus a differential mode section, then answer it wants final tally.

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int n,k,ans,cnt[N];
char s[N];
struct SuffixAutoMachine{
	int tot,last,ch[N*2][26],fa[N*2],len[N*2],epos[N*2];
	int newnode(int id){fa[++tot]=fa[id];len[tot]=len[id];memcpy(ch[tot],ch[id],sizeof(ch[tot]));return tot;}
	int head[N*2],to[N*2],nxt[N*2],total;
	void add(int u,int v){to[++total]=v;nxt[total]=head[u];head[u]=total;}
	void insert(int c){
		int p=last,np=last=newnode(0);
		len[np]=len[p]+1;epos[np]=1;
		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
		if(!p) {fa[np]=1;return;}
		int q=ch[p][c];
		if(len[q]==len[p]+1) {fa[np]=q;return;}
		int nq=newnode(q);len[nq]=len[p]+1;
		fa[q]=fa[np]=nq;
		for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
	}
	void dfs(int u){
		for(int i=head[u];i;i=nxt[i]) dfs(to[i]),epos[u]+=epos[to[i]];
		if(epos[u]==k) cnt[len[fa[u]]+1]++,cnt[len[u]+1]--;
	}
	void init(){
		tot=last=total=0;
		memset(head,0,sizeof(head));
		memset(epos,0,sizeof(epos));
		last=newnode(0);
		for(int i=1;i<=n;i++) insert(s[i]-'a');
		for(int i=2;i<=tot;i++) add(fa[i],i);
		dfs(1);
	}
}sam;

void solve(){
	memset(cnt,0,sizeof(cnt));
	scanf("%s%d",s+1,&k);
	n=strlen(s+1);
	ans=0;
	sam.init();
	for(int i=1;i<=n;i++){
		cnt[i]+=cnt[i-1];
		if(cnt[i]>=cnt[ans]) ans=i;
	}
	printf("%d\n",cnt[ans]>0?ans:-1);
}

int main(){
	int T;scanf("%d",&T);
	while(T--) solve();
	return 0;
}

Guess you like

Origin www.cnblogs.com/BakaCirno/p/12670814.html