zoukankan      html  css  js  c++  java
  • HDU6194 string string string(后缀自动机)

    HDU-6194 string string string(后缀自动机)

    这个题用后缀自动机做真的简单

    统计一下每个状态\(|endpos|\)是否等于\(k\)就能得到答案

    #include<bits/stdc++.h>
    using namespace std;
    
    #define reg register
    typedef long long ll;
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    #define pb push_back
    template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
    template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
    
    char IO;
    template<class T=int> T rd(){
    	T s=0;
    	int f=0;
    	while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    	do s=(s<<1)+(s<<3)+(IO^'0');
    	while(isdigit(IO=getchar()));
    	return f?-s:s;
    }
    
    const int N=2e5+10;
    
    
    int n,k;
    char s[N];
    int trans[N][26],link[N],stcnt,len[N],lst,sz[N];
    
    struct Edge{
    	int to,nxt;
    }e[N];
    int head[N],ecnt;
    void AddEdge(int u,int v) {
    	e[++ecnt]=(Edge){v,head[u]};
    	head[u]=ecnt;
    }
    
    void Init(){
    	link[0]=-1,len[0]=0;
    	rep(i,0,stcnt) {
    		head[i]=0,sz[i]=0;
    		rep(j,0,25) trans[i][j]=0;
    	}
    	stcnt=lst=ecnt=0;
    }
    
    void Extend(int c) {
    	int cur=++stcnt,p=lst;
    	len[cur]=len[lst]+1,sz[cur]=1;
    	while(~p && !trans[p][c]) trans[p][c]=cur,p=link[p];
    	if(p==-1) link[cur]=0;
    	else {
    		int q=trans[p][c];
    		if(len[q]==len[p]+1) link[cur]=q;
    		else {
    			int clone=++stcnt;
    			memcpy(trans[clone],trans[q],104);
    			link[clone]=link[q];
    			len[clone]=len[p]+1;
    			while(~p && trans[p][c]==q) trans[p][c]=clone,p=link[p];
    			link[cur]=link[q]=clone;
    		}
    	}
    	lst=cur;
    }
    
    ll ans;
    void dfs(int u) {
    	for(reg int i=head[u];i;i=e[i].nxt) {
    		int v=e[i].to;
    		dfs(v);
    		sz[u]+=sz[v];
    	}
    	if(u &&	sz[u]==k) ans+=max(0,len[u]-len[link[u]]);
    }
    
    int main(){
    	rep(kase,1,rd()){ 
    		k=rd();scanf("%s",s+1),n=strlen(s+1);
    		Init();
    		rep(i,1,n) Extend(s[i]-'a');
    		rep(i,1,stcnt) AddEdge(link[i],i);
    		ans=0,dfs(0),printf("%lld\n",ans);
    	}
    }
    
    
  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/chasedeath/p/12216712.html
Copyright © 2011-2022 走看看