ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU6138 Fleet of the Eternal Throne (GSAM)

2021-10-04 11:01:22  阅读:157  来源: 互联网

标签:Throne node int siz rep Eternal len Fleet now


HDU6138 Fleet of the Eternal Throne

Mean

给定\(n\)个字符串,\(m\)次询问\((m<=100)\),每次询问第\(L\)个字符串和第\(R\)个字符串的所有公共子串中,最长的公共子串,满足其是\(n\)个字符串中任意一个的前缀,输出其最长的长度。

Sol

GSAM

注意到\(m\)只有100,每次暴力的将询问的\(L\)串和\(R\)串建出广义后缀自动机,每个状态记录其在\(L\)串中出现的次数和在\(R\)串中出现的次数\(siz[i][0]和siz[i][1]\),跑一遍\(fail树\),向上传递维护一下。

随后依次遍历\(n\)个字符串,注意不允许失配,因为要求的是前缀。

把所有的合法前缀长度求个\(max\)即可。

复杂度\(O(nm)\).

Code

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
#define lowbit(x) (x&(-x))
#define debug(x) cout<<#x<<" :"<<x<<endl
#define debug1(x) cout<<#x<<" :"<<x<<" "
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N=2e5+20;
const int MAX=10000007;
inline int read() {
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}
    return x*f;
}

inline void out(int x) {   
    if(x>9) out(x/10);   
    putchar(x%10+'0'); 
}     
int q[N];
struct Node{
    int len,fa;
    int ch[10];
}node[N*2];
int tot=1,last=1;
int siz[N*2][3];
int extend(int c,int last,int id){
    if(node[last].ch[c]){
        int p = last,x = node[p].ch[c];
        if(node[p].len + 1 == node[x].len){//特判1
            siz[x][id]=1;
            return x;
        }
        else{//特判2
            int y = ++tot;node[y].len = node[p].len+1;
            for(int i=0;i<=9;++i)node[y].ch[i] = node[x].ch[i];
            while(p&&node[p].ch[c]==x)node[p].ch[c]=y,p=node[p].fa;
            node[y].fa=node[x].fa,node[x].fa=y;
            siz[y][id]=1;
            return y;
        }
    }

    int p = last ,np = last = ++tot;
    node[np].len = node[p].len + 1;
    for(;p && !node[p].ch[c]; p = node[p].fa){
        node[p].ch[c] = np;
    }
    if(!p)node[np].fa = 1;
    else{
        int q = node[p].ch[c];
        if(node[q].len == node[p].len + 1){
            node[np].fa = q;
        }
        else{
            int nq = ++tot;
            node[nq] = node[q];
            node[nq].len = node[p].len+1;
            node[q].fa = node[np].fa = nq;
            for(;p && node[p].ch[c] == q;p = node[p].fa){
                node[p].ch[c] = nq;
            }
        }
    }
    siz[last][id]=1;
    return last;

}
void init(){
    rep(i,0,tot){
        rep(j,0,25){
            node[i].ch[j]=0;
        }
        node[i].fa=0;
        siz[i][0]=siz[i][1]=0;
    }
    tot=last=1;
}

int T,n,m;
string s[N];
char p[N];
int in[N*2];
void solve(){
    memset(in,0,sizeof in);
    queue<int>Q;
    rep(i,2,tot){
        in[node[i].fa]++;
    }
    rep(i,1,tot){
        if(!in[i])Q.push(i);
    }
    while(!Q.empty()){
        int x =Q.front();
        Q.pop();
        siz[node[x].fa][0]+=siz[x][0];
        siz[node[x].fa][1]+=siz[x][1];
        if(--in[node[x].fa]==0){
            Q.push(node[x].fa);
        }
    }
    int mx = 0;
    rep(i,1,n){
        int len =s[i].size();
        int now = 1;
        int val = 0;
        rep(j,0,len-1){
            int c = s[i][j]-'a';
            if(node[now].ch[c]){
                now = node[now].ch[c];
                if(siz[now][0]&&siz[now][1]){
                    val = j+1;
                }
            }
            else{
                break;
            }
        }
        mx = max(mx,val);   
    }
    printf("%d\n",mx);
}

int main(){
    T=read();
    while(T--){
        n=read();
        rep(i,1,n){
            scanf("%s",p);
            s[i].clear();
            int len = strlen(p);
            rep(j,0,len-1){
                s[i]+=p[j];
            }
        }
        m=read();
        rep(i,1,m){
            int l,r;
            l=read(),r=read();
            init();
            last = 1;
            for(int j=0,len=s[l].size();j<len;++j){
                last = extend(s[l][j]-'a',last,0);
            }
            last = 1;
            for(int j=0,len=s[r].size();j<len;++j){
                last = extend(s[r][j]-'a',last,1);
            }
            solve();
        }
    }
    return 0;
}

标签:Throne,node,int,siz,rep,Eternal,len,Fleet,now
来源: https://www.cnblogs.com/quuns/p/15365963.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有