zoukankan      html  css  js  c++  java
  • [SDOI2008] Sandy的卡片

    题目链接:戳我

    差分之后,就是求n个串的最长公共子串了。

    可以先针对一个跑sam,然后其他串在上面做匹配;详情请见这里

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 1000000 
    using namespace std;
    int T,k,last=1,tot=1,n;
    int a[MAXN],c[MAXN],ans[MAXN],sum[MAXN],pre[MAXN],s[MAXN];
    struct Node{int son[26],ff,len;}t[MAXN<<1];
    inline void extend(int c)
    {
        int p=last,np=++tot;last=np;
        t[np].len=t[p].len+1;
        while(p&&!t[p].son[c]) t[p].son[c]=np,p=t[p].ff;
        if(p==0) t[np].ff=1;
        else
        {
            int q=t[p].son[c];
            if(t[q].len==t[p].len+1) t[np].ff=q;
            else
            {
                int nq=++tot;
                t[nq]=t[q],t[nq].len=t[p].len+1;
                t[q].ff=t[np].ff=nq;
                while(p&&t[p].son[c]==q) t[p].son[c]=nq,p=t[p].ff;
            }
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        int len;
        scanf("%d",&len);
        for(int i=1;i<=len;i++) scanf("%d",&pre[i]);
        len--;
        for(int i=1;i<=len;i++) s[i]=pre[i+1]-pre[i]; 
        for(int i=1;i<=len;i++) extend(s[i]);
        for(int i=1;i<=tot;i++) c[t[i].len]++;
        for(int i=1;i<=tot;i++) c[i]+=c[i-1];
        for(int i=1;i<=tot;i++) a[c[t[i].len]--]=i;
        for(int i=1;i<=tot;i++) ans[i]=t[i].len;
        int maomao;
        for(int kkk=2;kkk<=n;kkk++)
        {
            scanf("%d",&maomao);
            for(int i=1;i<=maomao;i++) scanf("%d",&pre[i]);
            maomao--;
            for(int i=1;i<=maomao;i++) s[i]=pre[i+1]-pre[i];
            // for(int i=1;i<=maomao;i++) printf("%d ",s[2][i]); puts("");
            int now=1,cur_ans=0;
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=maomao;i++)
            {
                if(t[now].son[s[i]]) cur_ans++,now=t[now].son[s[i]];
                else
                {
                    while(now&&!t[now].son[s[i]]) now=t[now].ff;
                    if(now==0) cur_ans=0,now=1;
                    else cur_ans=t[now].len+1,now=t[now].son[s[i]];
                }
                sum[now]=max(sum[now],cur_ans);
            }
            for(int i=tot;i>=1;i--)
            {
                int cur=a[i];
                sum[t[cur].ff]=max(sum[t[cur].ff],sum[cur]);
            }
            for(int i=1;i<=tot;i++) ans[i]=min(ans[i],sum[i]);
        }
        int maxx=0;
        for(int i=1;i<=tot;i++) maxx=max(maxx,ans[i]);
        printf("%d
    ",maxx+1);
        return 0;
    }
    
  • 相关阅读:
    [原][osg]Geometry详解
    [osg]节点遍历nodevisitor浅析
    [原][osg]osgconv浅析
    [原][游戏][攻略]仙之侠道玖章-- --从入门到放弃
    [转][linux]简单的linux下的tcp/udp
    [转][c++][跨平台]c++跨平台开发小结
    人机交互,来和我猜拳吧!
    从零开始学测试【1】测试方法术语总结
    从零开始学测试【2】网页登录界面
    JSP 和 ASP.NET 谁能主宰未来【转】
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10746085.html
Copyright © 2011-2022 走看看