• Codeforces Round #129 (Div. 1)E. Little Elephant and Strings


    题意:有n个串,询问每个串有多少子串在n个串中出现了至少k次.
    题解:sam,每个节点开一个set维护该节点的字符串有哪几个串,启发式合并set,然后在sam上走一遍该串,对于每个可行的串,所有的fail都是可行的直接加上len,不可行就往fail上跳.
    for(int i=0;s[i];i++)有问题!!!!

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    //#define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const ull ba=233;
    const db eps=1e-5;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=100000+10,maxn=1000000+10,inf=0x3f3f3f3f;
    
    int n,k;
    char s[N];
    vector<char>v[N];
    struct SAM{
        int last,cnt;
        int ch[N<<1][26],fa[N<<1],l[N<<1];
        int sz[N<<1],id[N<<1];
        set<int>st[N<<1];
        vi son[N<<1];
        SAM(){cnt=1;}
        void ins(int c){
            if(ch[last][c])
            {
                int p=last,q=ch[last][c];
                if(l[q]==l[p]+1)last=q;
                else
                {
                    int nq=++cnt;l[nq]=l[p]+1;
                    memcpy(ch[nq],ch[q],sizeof ch[q]);
                    fa[nq]=fa[q];fa[q]=last=nq;
                    for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
                }
                return ;
            }
            int p=last,np=++cnt;last=np;l[np]=l[p]+1;
            for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
            if(!p)fa[np]=1;
            else
            {
                int q=ch[p][c];
                if(l[p]+1==l[q])fa[np]=q;
                else
                {
                    int nq=++cnt;l[nq]=l[p]+1;
                    memcpy(ch[nq],ch[q],sizeof(ch[q]));
                    fa[nq]=fa[q];fa[q]=fa[np]=nq;
                    for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
                }
            }
        }
        void build(int id)
        {
            last=1;int len=strlen(s);
            for(int i=0;i<len;i++)ins(s[i]-'a'),st[last].insert(id);
        }
        void dfs(int u)
        {
            for(int x:son[u])
            {
                dfs(x);
                if(st[id[u]].size()<st[id[x]].size())
                {
                    for(int p:st[id[u]])st[id[x]].insert(p);
                    st[id[u]].clear();id[u]=id[x];
                }
                else
                {
                    for(int p:st[id[x]])st[id[u]].insert(p);
                    st[id[x]].clear();
                }
            }
            sz[u]=st[id[u]].size();
        }
        void cal()
        {
            for(int i=2;i<=cnt;i++)son[fa[i]].pb(i),id[i]=i;
            id[1]=1;
            dfs(1);
            for(int i=1;i<=n;i++)
            {
                int now=1;ll ans=0;
                for(int j=0;j<v[i].size();j++)
                {
                    now=ch[now][v[i][j]-'a'];
                    while(now!=1&&sz[now]<k)now=fa[now];
                    ans+=l[now];
                }
                printf("%lld ",ans);
            }
            puts("");
        }
    }sam;
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            int n=strlen(s);
            for(int j=0;j<n;j++)v[i].pb(s[j]);
            sam.build(i);
        }
        sam.cal();
        return 0;
    }
    /********************
    
    ********************/
    
  • 相关阅读:
    映射和分析
    文档操作
    向 Nginx 主进程发送 USR1 信号
    ES集群7.3.0设置快照,存储库进行索引备份和恢复等
    ES7.3.0配置邮件告警
    Elasticsearch 史上最全最常用工具清单
    Grok在线调试网址
    Linux 小知识翻译
    Linux 小知识翻译
    Linux 小知识翻译
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10749949.html
Copyright © 2020-2023  润新知