zoukankan      html  css  js  c++  java
  • SAM入门

    学了两天,会了点皮毛,这里只放代码。

    P3804

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 1e6 + 5;
    struct node
    {
        int ch[27];
        int len,fa;
        node()
        {
            clean(ch);
            len = 0;
        }
    }dian[N << 1];
    int las = 1,tot = 1;
    int len;
    char s[N];
    int buc[N << 1],siz[N << 1],pos[N << 1];
    inline void add(int c)
    {
        int p = las;int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        for(;p && !dian[p].ch[c];p = dian[p].fa)
        dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1;
        else
        {
            int q = dian[p].ch[c];
            if(dian[q].len == dian[p].len + 1) dian[np].fa = q;
            else
            {
                int nq = ++tot;
                dian[nq] = dian[q];
                dian[nq].len = dian[p].len + 1;
                dian[q].fa = dian[np].fa = nq;
                for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
            }
        }
        siz[np] = 1;
    }
    /*void add(int c)
    {
        int p=las;int np=las=++tot;
        dian[np].len=dian[p].len+1;
        for(;p&&!dian[p].ch[c];p=dian[p].fa)dian[p].ch[c]=np;
        if(!p)dian[np].fa=1;//以上为case 1
        else
        {
            int q=dian[p].ch[c];
            if(dian[q].len==dian[p].len+1)dian[np].fa=q;//以上为case 2
            else
            {
                int nq=++tot;dian[nq]=dian[q];
                dian[nq].len=dian[p].len+1;
                dian[q].fa=dian[np].fa=nq; 
                for(;p&&dian[p].ch[c]==q;p=dian[p].fa)dian[p].ch[c]=nq;//以上为case 3
            }
        }
        siz[las = np] = 1;
    }*/
    inline int dfs()
    {
        int ret = 0;
        duke(i,1,tot)
            ++buc[dian[i].len];
        duke(i,1,tot)
            buc[i] += buc[i - 1];
        duke(i,1,tot)
        pos[buc[dian[i].len]--] = i;
        for(int i = tot;i;i--)
        {
            int now = pos[i];
            siz[dian[now].fa] += siz[now];
            if(siz[now] > 1)
            ret = max(ret,siz[now] * dian[now].len);
        }
        return ret;
    }
    int main()
    {
        scanf("%s",s);
        len = strlen(s);
        duke(i,0,len - 1)
        {
            add(s[i] - 'a');
        }
        printf("%d
    ",dfs());
        return 0;
    }

    SP1811

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 250005;
    struct node
    {
        int fa,len;
        int ch[27];
        node()
        {
            len = 0;
            clean(ch);
        }
    }dian[N << 1];
    int tot = 1,las = 1,len1,len2;
    char s1[N],s2[N];
    inline void add(int c)
    {
        int p = las;int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        for(;p && !dian[p].ch[c];p = dian[p].fa)
        dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1;
        else
        {
            int q = dian[p].ch[c];
            if(dian[q].len == dian[p].len + 1) dian[np].fa = q;
            else
            {
                int nq = ++tot;
                dian[nq] = dian[q];
                dian[nq].len = dian[p].len + 1;
                dian[q].fa = dian[np].fa = nq;
                for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
            }
        }
    }
    inline int Max(int x,int y)
    {
        return x < y ? y : x;
    }
    inline int lcs(char *s)
    {
        int n = strlen(s),ret = 0;
        for(int i = 0,p = 1,l = 0;i < n;++i)
        {
            int c = s[i] - 'a';
            if(dian[p].ch[c] != 0) l++,p = dian[p].ch[c];
            else
            {
                for(;p && !dian[p].ch[c];p = dian[p].fa) ;
                if(!p) l = 0,p = 1;
                else
                {
                    l = dian[p].len + 1;
                    p = dian[p].ch[c];
                }
            }
            ret = Max(ret,l);
        }
        return ret;
    }
    int main()
    {
        scanf("%s",s1);
        scanf("%s",s2);
        len1 = strlen(s1);
        len2 = strlen(s2);
        for(register int i = 0;i < len1;++i)
        {
            add(s1[i] - 'a');
        }
        printf("%d
    ",lcs(s2));
        return 0;
    }

    SP1812

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 1e5 + 5;
    struct node
    {
        int fa,len;
        int ch[27];
        node()
        {
            clean(ch);
            len = 0;
        }
    } dian[N << 1];
    char s1[N],s2[N];
    int las = 1,tot = 1;
    inline void add(int c)
    {
        int p = las;
        int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        for(; p && !dian[p].ch[c]; p = dian[p].fa)
            dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1;
        else
        {
            int q = dian[p].ch[c];
            if(dian[q].len == dian[p].len + 1) dian[np].fa = q;
            else
            {
                int nq = ++tot;
                dian[nq] = dian[q];
                dian[nq].len = dian[p].len + 1;
                dian[q].fa = dian[np].fa = nq;
                for(; p && dian[p].ch[c] == q; p = dian[p].fa) dian[p].ch[c] = nq;
            }
        }
    }
    int pos[N << 1],buc[N << 1],Max[N << 1],Min[N << 1];
    inline void dfs(char *s)
    {
        int n = strlen(s);
        for(int i = 0,p = 1,l = 0; i < n; ++i)
        {
            int c = s[i] - 'a';
            for(; p && !dian[p].ch[c];) p = dian[p].fa,l = dian[p].len;
            if(!p) l = 0,p = 1;
            else
            {
                l ++;
                p = dian[p].ch[c];
                Max[p] = max(Max[p],l);
            }
        }
        for(int i = tot; i >= 1; --i)
        {
            int now = pos[i],f = dian[now].fa;
            Max[f] = max(Max[f],min(Max[now],dian[f].len));
            Min[now] = min(Min[now],Max[now]);
            Max[now] = 0;
        }
    }
    void sort()
    {
        duke(i,1,tot)
        ++buc[dian[i].len];
        duke(i,1,tot)
        buc[i] += buc[i - 1];
        duke(i,1,tot)
        pos[buc[dian[i].len] --] = i;
    }
    int main()
    {
        scanf("%s",s1);
        int len1 = strlen(s1);
        for(register int i = 0; i < len1; ++i)
        {
            add(s1[i] - 'a');
        }
        sort();
        memset(Min,0x3f,sizeof(Min));
        clean(Max);
        while(scanf("%s",s2) != EOF)
        {
            dfs(s2);
        }
        int ans = 0;
        duke(i,1,tot)
        ans = max(ans,Min[i]);
        printf("%d
    ",ans);
        return 0;
    }

     P2852 [USACO06DEC]牛奶模式Milk Patterns

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 2e4 + 5;
    struct node
    {
        int len,fa;
        int ch[27];
        node()
        {
        clean(ch);
        len = 0;
        }
    }dian[N << 1];
    int las = 1,tot = 1;
    int n,k;
    int x,pos[N << 1],siz[N << 1];
    void add(int c)
    {
        int p = las;int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        siz[np] = 1;
        for(;p && !dian[p].ch[c];p = dian[p].fa)
        dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1;
        else
        {
        int q = dian[p].ch[c];
        if(dian[q].len == dian[p].len + 1)
            dian[np].fa = q;
        else
        {
            int nq = ++tot;
            dian[nq] = dian[q];
            dian[nq].len = dian[p].len + 1;
            dian[q].fa = dian[np].fa = nq;
            for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
        }
        }
    }
    int dfs()
    {
        int ret = 0;
        for(int i = 1;i <= tot;i++)
        pos[i] = i;
        sort(pos + 1,pos + tot + 1,[=](int &a,int &b){return dian[a].len > dian[b].len;});
        for(int i = 1;i <= tot;++i)
        {
        siz[dian[pos[i]].fa] += siz[pos[i]];
        if(siz[pos[i]] >= k)
        {
            ret = max(ret,dian[pos[i]].len);
        }
        }
        return ret;
    }
    int main()
    {
        read(n);read(k);
        for(int i = 1;i <= n;++i)
        read(x),add(x);
        printf("%d
    ",dfs());
        return 0;
    }

     P3975 [TJOI2015]弦论

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 5e5 + 5;
    struct node
    {
        int len,fa;
        int ch[27];
    }dian[N << 1];
    char s[N];
    int las = 1,tot = 1;
    int n,k,flg;
    int x,pos[N << 1],siz[N << 1],buc[N << 1],sum[N << 1];
    void add(int c)
    {
        int p = las;int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        siz[np] = 1;
        for(;p && !dian[p].ch[c];p = dian[p].fa)
        dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1;
        else
        {
        int q = dian[p].ch[c];
        if(dian[q].len == dian[p].len + 1)
            dian[np].fa = q;
        else
        {
            int nq = ++tot;
            dian[nq] = dian[q];
            dian[nq].len = dian[p].len + 1;
            dian[q].fa = dian[np].fa = nq;
            for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
        }
        }
    }
    inline void dfs()
    {
        for(int i = 1; i <= tot; ++i)
        ++buc[dian[i].len];
        for(int i = 1; i <= tot; ++i)
        buc[i] += buc[i - 1];
        for(int i = 1; i <= tot; ++i)
        pos[buc[dian[i].len]--] = i;
        for(int i = tot; i; --i)
        siz[dian[pos[i]].fa] += siz[pos[i]];
        for(int i = 1; i <= tot; ++i)
        {
        if(!flg)
            sum[i] = siz[i] = 1;
        else
            sum[i] = siz[i];
        }
        siz[1] = 0;
        for(int i = tot; i; --i)
        for(int j = 0; j < 26; ++j)
            if(dian[pos[i]].ch[j])
            sum[pos[i]] += sum[dian[pos[i]].ch[j]];
    }
    inline void print(int k)
    {
        if(sum[1] < k)
        {
        printf("-1
    ");
        return;
        }
        int now = 1;
        k -= siz[now];
        while(k)
        {
        int c = 0;
        while(k > sum[dian[now].ch[c]])
        {
            k -= sum[dian[now].ch[c++]];
        }
        now = dian[now].ch[c];
        putchar('a' + c);
        k -= siz[now];
        }
    }
    int main()
    {
        scanf("%s",s);
        n = strlen(s);
        duke(i,0,n << 1)
        dian[i].len = 0,clean(dian[i].ch);
        duke(i,0,n - 1)
        add(s[i] - 'a');
        read(flg);read(k);
        dfs();
        print(k);
        puts("");
        return 0;
    }

     P4070 [SDOI2016]生成魔咒

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #include<map>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;++i)
    #define lv(i,a,n) for(register int i = a;i >= n;--i)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 2e5 + 5;
    struct node
    {
        int fa;
        ll len;
        map <int,int> ch;
    }dian[N << 1];
    char s[N];
    int las = 1,tot = 1;
    int n,k;
    ll ans = 0;
    int x;
    void add(int c)
    {
        int p = las;int np = las = ++tot;
        dian[np].len = dian[p].len + 1;
        for(;p && !dian[p].ch[c];p = dian[p].fa)
        dian[p].ch[c] = np;
        if(!p) dian[np].fa = 1,ans += dian[np].len;
        else
        {
        int q = dian[p].ch[c];
        if(dian[q].len == dian[p].len + 1)
            dian[np].fa = q,ans += dian[np].len - dian[q].len;
        else
        {
            int nq = ++tot;
            dian[nq] = dian[q];
            dian[nq].len = dian[p].len + 1;
            ans -= dian[q].len - dian[dian[q].fa].len;
            dian[q].fa = dian[np].fa = nq;
            ans += dian[nq].len - dian[dian[nq].fa].len;
            ans += dian[q].len - dian[nq].len;
            ans += dian[np].len - dian[nq].len;
            for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq;
        }
        }
    }
    int main()
    {
        read(n);
        while(n--)
        {
        int c;
        read(c);
        add(c);
        printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    总结php删除html标签和标签内的内容的方法
    php正则验证手机、邮箱
    php正则匹配到字符串里面的a标签
    PHP 使用try catch,捕获异常
    Apache漏洞利用与安全加固实例分析
    php json接口demo
    PHP 把MYSQL重复ID 二维数组重组为三维数组
    文件扩展关联命令(assoc)
    修改文件属性(attrib)
    文件比较命令(fc)
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10474131.html
Copyright © 2011-2022 走看看