gggyt  
没谁离不开谁

  题目链接:https://vjudge.net/contest/31226#problem/A

  题意:给你两个字符串,问你两个字符串最长的公共字串有多长。

  是后缀自动机的模板题(看了下后缀自动机,感觉半懂半不懂,做做模板题,理解下,再继续做)

  开始忘了初始化=。=,然后一直T,哇,这个错不能再犯了。

 

/** @xigua */
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
#define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a))
#define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a))
#define CLR(x) memset(x, 0, sizeof(x))
#define sf scanf
#define pf printf
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 250000  + 1000;
const int ma = 1e5 + 1000;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e17 + 5;
const db eps = 1e-6;
const int MAXN = 2e5+1e3;
struct SAM{
    int ch[maxn<<1][26];
    int fa[maxn<<1], len[maxn<<1];
    int cnt, last, root;
    void init() {
        root=1;
        memset(ch, 0, sizeof(ch));
        memset(fa, 0, sizeof(fa));
        last=cnt=root;
    }
    void add(int c) {
        int p=last, np=last=++cnt;
        len[np]=len[p]+1;
        while(!ch[p][c] && p) {
            ch[p][c]=np;
            p=fa[p];
        }
        if (p==0)  fa[np]=1;
        else {
            int q = ch[p][c];
            if(len[p] + 1 == len[q]) {
                fa[np] = q;
            }
            else {
                int nq = ++cnt;
                len[nq] = len[p] + 1;
                memcpy(ch[nq], ch[q], sizeof ch[q]);
                fa[nq] = fa[q];
                fa[q] = fa[np] = nq;
                while(ch[p][c] == q && p) {
                    ch[p][c] = nq;
                    p = fa[p];
                }
            }
        }
    }
    int find(char *s) {
        int p=root, l=0, c=0;
        int lenn=strlen(s);
        for(int i = 0; i < lenn; i++) {
            if(ch[p][s[i] - 'a']) {
                p = ch[p][s[i] - 'a'];
                c++;
            }
            else {
                while(p&&!ch[p][s[i]-'a'])  p=fa[p];
                if (!p)  c=0, p=1;
                else  c=len[p]+1, p=ch[p][s[i]-'a'];
            }
            l = max(l, c);
        }
        printf("%d\n", l);
    }
}sam;
char s[maxn];
void solve() {
    scanf("%s", s);
    int lenn=strlen(s);
    sam.init();
    for (int i=0; i<lenn; i++) {
        sam.add(s[i]-'a');
    }
    scanf("%s", s);
    sam.find(s);
}
int main() {
    int t = 1, cas = 1;
    //freopen("in.txt", "r", stdin);
   // freopen("out.txt", "w", stdout);
    //scanf("%d", &t);
    while(t--) {
       // printf("Case %d: ", cas++);
        solve();
    }
    return 0;
}

 

   做题竟然T了,我的板子不行啊

  下面是个新板子

/** @xigua */
#include <stdio.h>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
#define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a))
#define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a))
#define CLR(x) memset(x, 0, sizeof(x))
#define sf scanf
#define pf printf
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 1e5 + 1000;
const int ma = 1e5 + 1000;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e17 + 5;
const db eps = 1e-6;
const int MAXN = 2e5+1e3;
char pool[MAXN];

struct Str{
    int st, len;
}str[MAXN];
struct state {
    int len, pre, ch[26];
};
struct SAM {
    int sz, last;
    state st[MAXN];
    state& operator[] (int x) {
        return st[x];
    }
    void clear(int x) {
        CLR(st[x].ch);
    }
    void init() {
        sz=1, last=0;
        st[0].len=0, st[0].pre=-1;
        clear(0);
    }
    void add(int c) {
        int cur=sz++, p;
        clear(cur);
        st[cur].len=st[last].len+1;
        for(p=last; p!=-1&&!st[p].ch[c]; p=st[p].pre)
            st[p].ch[c]=cur;
        if(p==-1) st[cur].pre=0;
        else {
            int q=st[p].ch[c];
            if(st[q].len==st[p].len+1)
                st[cur].pre=q;
            else {
                int clone=sz++;
                st[clone]=st[q];
                st[clone].len=st[p].len+1;
                st[cur].pre=st[q].pre=clone;
                for(; p!=-1&&st[p].ch[c]==q; p=st[p].pre)
                    st[p].ch[c]=clone;
            }
        }
        last=cur;
    }
    int find(string t) {//查询lcs
        int now=0, l=0, ans=0;
        int len=t.length();
        for (int i=0; i<len; i++) {
            while(now&&!st[now].ch[t[i]-'a']) {
                now=st[now].pre;
                l=st[now].len;
            }
            if(st[now].ch[t[i]-'a']) {
                ++l;
                now=st[now].ch[t[i]-'a'];
            }
            ans=max(l, ans);
        }
        return ans;
    }
} sam;
string a[maxn];
bool check(int sel, int n) {
    for (int i=0; i<n; i++) {
        if (i!=sel) {
            if (sam.find(a[i])!=a[i].length())  return 0;
        }
    }
    return true;
}
char ans[maxn];
void solve() {
    int n;  scanf("%d", &n);
    str[0].st=0;
    int sel=0, maxx=0;
    for (int i=0; i<n; i++) {
        scanf("%s", pool);
        int len=strlen(pool);
        if (len>maxx)  {
            maxx=len;
            sel=i;
        }
        a[i]=string(pool);
    }
    sam.init();
    int len=a[sel].length();
    for (int i=0; i<len; i++)
        sam.add(a[sel][i]-'a');
    for (int i=0; i<len; i++)
        ans[i]=a[sel][i];
    if(check(sel,n)) {
        int l=a[sel].length();
        for (int i=0; i<len; i++)
            printf("%c", ans[i]);
            puts("");
    }
    else puts("No");
}
int main() {
    int t = 1, cas = 1;
    //freopen("in.txt", "r", stdin);
   // freopen("out.txt", "w", stdout);
    scanf("%d", &t);
    while(t--) {
       // printf("Case %d: ", cas++);
        solve();
    }
    return 0;
}

   拓扑排序

/** @xigua */
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <cstring>
#include <queue>
#include <set>
#include <string>
#include <map>
#include <climits>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 200000 + 5;
const int mod = 1e9 + 7;
const int INF = 1e8 + 5;
const ll inf = 1e15 + 5;
const db eps = 1e-6;
char s[maxn];
int Min[maxn<<1], Max[maxn<<1];
int ch[maxn<<1][26];
int fa[maxn<<1];
int len[maxn<<1];
int cnt, last;
int c[maxn<<1], pt[maxn<<1];

void init() {
    memset(ch, 0, sizeof(ch));
    memset(fa, 0, sizeof(fa));
    memset(Min, INF, sizeof(Min));
    memset(pt, 0, sizeof(pt));
    memset(c, 0, sizeof(c));
    last=cnt=1;
}
void add(int c) {
    int p = last, np = last = ++cnt;
    Min[np]=len[np] = len[p] + 1;
    while(!ch[p][c] && p) {
        ch[p][c] = np;
        p = fa[p];
    }
    if(p == 0) fa[np] = 1;
    else {
        int q = ch[p][c];
        if(len[p] + 1 == len[q]) {
            fa[np] = q;
        } else {
            int nq = ++cnt;
            len[nq] = len[p] + 1;
            memcpy(ch[nq], ch[q], sizeof ch[q]);
            fa[nq] = fa[q];
            fa[q] = fa[np] = nq;
            while(ch[p][c] == q && p) {
                ch[p][c] = nq;
                p = fa[p];
            }
        }
    }
}

void solve() {
    scanf("%s", s);
    int lenn = strlen(s);
    init();
    for(int i = 0; i < lenn; i++) {
        add(s[i] - 'a');
    }
    for (int i=1; i<=cnt; i++)
        c[len[i]]++;
    for (int i=1; i<=cnt; i++)
        c[i]+=c[i-1];
    for (int i=cnt; i>=1; i--)
        pt[c[len[i]]--]=i;
    while(~scanf("%s", s)) {
        memset(Max, 0, sizeof(Max));
        lenn = strlen(s);
        int p = 1;
        int c = 0;
        for(int i = 0; i < lenn; i++) {
            if(ch[p][s[i] - 'a']) {
                p = ch[p][s[i] - 'a'];
                c++;
            }
            else {
                while(p&&!ch[p][s[i]-'a'])  p=fa[p];
                if (!p)  c=0, p=1;
                else  c=len[p]+1, p=ch[p][s[i]-'a'];
            }
            Max[p]=max(Max[p], c);
        }
        for (int i=cnt; i>=1; i--) {
            p=pt[i];
            if (Max[p])  Max[fa[p]]=len[fa[p]];
        }
        for (int i=1; i<=cnt; i++)
            Min[i]=min(Min[i], Max[i]);
    }
    int ans=0;
    for (int i=1; i<=cnt; i++)
        ans = max(ans, Min[i]);
    printf("%d\n", ans);
}
int main() {
    int t = 1;
    //freopen("in.txt", "r", stdin);
  //  scanf("%d", &t);
    while(t--)
        solve();
    return 0;
}

 

posted on 2017-09-13 08:33  gggyt  阅读(397)  评论(0编辑  收藏  举报