zoukankan      html  css  js  c++  java
  • 后缀自动机模板题

      题目链接: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
    ", 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
    ", ans);
    }
    int main() {
        int t = 1;
        //freopen("in.txt", "r", stdin);
      //  scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    SQL 大数据查询如何进行优化?
    事件和委托的区别
    虚方法(virtual)和抽象方法(abstract)的和接口(interface)的区别
    高并发的秒杀
    C#算法
    口试C#概念
    口试Linq题
    口试大数据及大并发问题
    Windows下MongoDB安装
    MongoDB简单介绍
  • 原文地址:https://www.cnblogs.com/gggyt/p/7513190.html
Copyright © 2011-2022 走看看