码迷,mamicode.com
首页 > 其他好文 > 详细

SAM入门

时间:2019-03-04 23:48:02      阅读:250      评论:0      收藏:0      [点我收藏+]

标签:scanf   ==   cti   tchar   turn   mes   template   putc   pac   

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

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\n",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\n",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\n",ans);
    return 0;
}

 

SAM入门

标签:scanf   ==   cti   tchar   turn   mes   template   putc   pac   

原文地址:https://www.cnblogs.com/DukeLv/p/10474131.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!