zoukankan      html  css  js  c++  java
  • [HDU5769] Substring

    Description

    给你一个串,问你含某个特定的字符的本质不同子串有多少种。

    Solution

    (f[p]) 表示从结点 (p) 沿着转移边走能到达的不同合法子串有多少种

    设题中要求要走的字母为 (c)

    对于 (p + c o q)(f[p] leftarrow siz(q))

    对于 (p+? o q, ? eq c)(f[p] leftarrow f[q])

    其中 (siz(p)) 表示 (p) 点往后可以转移到的本质不同子串数目

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200005;
    struct SAM
    {
        int len[N], ch[N][26], fa[N], ind, last;
        int t[N], a[N], cnt[N], vis[N];
        long long f[N];
        SAM()
        {
            ind = last = 1;
        }
        void init()
        {
            ind = last = 1;
            memset(len,0,sizeof len);
            memset(ch,0,sizeof ch);
            memset(fa,0,sizeof fa);
            memset(t,0,sizeof t);
            memset(a,0,sizeof a);
            memset(cnt,0,sizeof cnt);
            memset(f,0,sizeof f);
            memset(vis,0,sizeof vis);
        }
        inline void extend(int id)
        {
            int cur = (++ ind), p;
            len[cur] = len[last] + 1;
            cnt[cur] = 1;
            for (p = last; p && !ch[p][id]; p = fa[p]) ch[p][id] = cur;
            if (!p) fa[cur] = 1;
            else
            {
                int q = ch[p][id];
                if (len[q] == len[p] + 1) fa[cur] = q;
                else
                {
                    int tmp = (++ ind);
                    len[tmp] = len[p] + 1;
                    for(int i=0; i<26; i++) ch[tmp][i] = ch[q][i];
                    fa[tmp] = fa[q];
                    for (; p && ch[p][id] == q; p = fa[p]) ch[p][id] = tmp;
                    fa[cur] = fa[q] = tmp;
                }
            }
            last = cur;
        }
        void dfs0(int p,char chr)
        {
            vis[p]=1;
            cnt[p]=1;
            for(int i=0;i<26;i++)
            {
                if(ch[p][i])
                {
                    if(!vis[ch[p][i]])
                    {
                        dfs0(ch[p][i],chr);
                    }
                    cnt[p]+=cnt[ch[p][i]];
                }
            }
        }
        void dfs(int p,char chr)
        {
            vis[p]=1;
            for(int i=0;i<26;i++)
            {
                if(ch[p][i])
                {
                    if(!vis[ch[p][i]])
                    {
                        dfs(ch[p][i],chr);
                    }
                    if(i==chr-'a') f[p]+=cnt[ch[p][i]];
                    else f[p]+=f[ch[p][i]];
                }
            }
        }
        void solve(char chr)
        {
            /*for(int i=ind; i>=1; --i)
            {
                for(int j=0; j<26; j++)
                {
                    if(ch[i][j])
                    {
                        if(j==chr-'a') f[i]+=cnt[ch[i][j]];
                        else f[i]+=f[ch[i][j]];
                    }
                }
            }*/
            dfs0(1,chr);
            memset(vis,0,sizeof vis);
            dfs(1,chr);
        }
    } sam;
    
    long long solve()
    {
        ios::sync_with_stdio(false);
        string str;
        char t;
        cin>>str;
        t=str[0];
        cin>>str;
        sam.init();
        for(int i=0; i<str.length(); i++)
            sam.extend(str[i]-'a');
        sam.solve(t);
        return sam.f[1];
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        for(int i=1;i<=t;i++)
        {
            cout<<"Case #"<<i<<": "<<solve()<<endl;
        }
    }
    
    
  • 相关阅读:
    筛选数据
    sed实现路径替换
    mask rcnn
    py faster rcnn+ 1080Ti+cudnn5.0
    反对迭代0:停止拖延,开始迭代
    故事点数是对工时的度量
    放弃在每日站会上按成员逐个发言
    So Easy!7000元Scrum认证课1元抢~
    用leangoo怎么做需求管理及规划?(产品Backlog、用户故事)
    怎么用leangoo做需求管理?(用户故事地图)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13293743.html
Copyright © 2011-2022 走看看