• 【BZOJ-4180】字符串计数 后缀自动机 + 矩阵乘法


    4180: 字符串计数

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 146  Solved: 66
    [Submit][Status][Discuss]

    Description

    SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999。
     
    他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'。现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次操作选择T的一个子串,将其加入S的末尾。
     
    对于一个可构造出的字符串S,可能有多种构造方案,Oxer定义构造字符串S所需的操作次数为所有构造方案中操作次数的最小值。
     
    Oxer想知道对于给定的正整数N和字符串T,他所能构造出的所有长度为N的字符串S中,构造所需的操作次数最大的字符串的操作次数。
     
    蒟蒻yts1999当然不会做了,于是向你求助。

    Input

    第一行包含一个整数N,表示要构造的字符串长度。
     
    第二行包含一个字符串T,T的意义如题所述。

    Output

    输出文件包含一行,一个整数,为你所求出的最大的操作次数。

    Sample Input

    5
    ABCCAD

    Sample Output

    5

    HINT

    【样例说明】

    例如字符串"AAAAA",该字符串所需操作次数为5,不存在能用T的子串构造出的,且所需操作次数比5大的字符串。

    【数据规模和约定】

    对于100%的数据,1 ≤ N ≤ 10^18,1 ≤ |T| ≤ 10^5。

    Source

    By yts1999

    Solution

    人傻不会做...于是看的题解...

    Code

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    #define LL long long
    #define MAXN 500010
    #define INF (1LL<<62) 
     
    LL N;
    char S[MAXN];
     
    int last=1,sz=1,root=1,par[MAXN<<1],len[MAXN<<1],son[MAXN][4];
    LL f[MAXN][4];
    inline void Extend(int c)
    {
        int cur=++sz,p=last;
        len[cur]=len[p]+1;
        while (p && !son[p][c]) son[p][c]=cur,p=par[p];
        if (!p) par[cur]=root;
        else {
            int q=son[p][c];
            if (len[p]+1==len[q]) par[cur]=q;
            else {
                int nq=++sz;
                memcpy(son[nq],son[q],sizeof(son[nq]));
                len[nq]=len[p]+1; par[nq]=par[q];
                while (p && son[p][c]==q) son[p][c]=nq,p=par[p];
                par[q]=par[cur]=nq;
            }
        }
        last=cur;
    }
     
    bool visit[MAXN<<1];
    inline void Dfs(int now)
    {
        if (visit[now]) return;
        visit[now]=1;
        for (int c=0; c<4; c++)
            if (son[now][c]) 
                Dfs(son[now][c]),f[now][c]=INF;
            else f[now][c]=1;
        for (int c=0; c<4; c++)
            if (son[now][c])
                for (int cc=0; cc<4; cc++)
                    f[now][cc]=min(f[now][cc],f[son[now][c]][cc]+1);
    }
     
    struct Matrix{
        LL a[4][4];
        Matrix() {for (int i=0; i<4; i++) for (int j=0; j<4; j++) a[i][j]=INF;}
        LL* operator [](int x) {
            return a[x];
        }
    }X;
     
    Matrix operator * (Matrix &A,Matrix &B) {
        Matrix C;          
        for (int i=0; i<4; i++)
            for (int j=0; j<4; j++)
                for (int k=0; k<4; k++)
                    C[i][j]=min(C[i][j],A[i][k]+B[k][j]);
        return C;
    }
     
    Matrix operator ^ (Matrix x,LL y) {
        Matrix re;
        memset(re.a,0,sizeof(re.a));
        for (int i=0; i<4; i++) re[i][i]=1;
        for ( ; y; y>>=1,x=x*x) if (y&1) re=re*x;
        return re;
    }
     
    inline bool check(LL x)
    {
        Matrix B=X^x;   
        for (int i=0; i<4; i++)
            for (int j=0; j<4; j++)
                if (B[i][j]+1<=N) return 1;
        return 0; 
    }
     
    int main()
    {
        scanf("%lld%s",&N,S+1); int L=strlen(S+1);
         
        for (int i=1; i<=L; i++) Extend(S[i]-'A');
         
        Dfs(root);
         
        for (int i=0; i<4; i++)
            for (int j=0; j<4; j++)
                X[i][j]=f[son[root][i]][j];
         
    //  for (int i=0; i<4; i++,puts(""))
    //      for (int j=0; j<4; j++) printf("%I64d  ",X[i][j]==INF? -1:X[i][j]);
         
        LL l=0,r=N+1,mid,ans=0;
        while (l<=r) {
            mid=(l+r)>>1;
            if (check(mid)) l=mid+1;
                else r=(ans=mid)-1;
        }
        printf("%lld
    ",ans);
         
        return 0;
    }
    /*
    5
    ABCCAD
    */
    

      

  • 相关阅读:
    数据库版本管理工具flyway
    spring webapp的配置文件放置在项目外的方法
    logback
    linux as4 bind9 设置进程中的一些小效果
    设置/勾销Debian的屏保
    Linux内存:内存管理的天禀
    用YUM晋级CentOS体系中PHP和MySQL
    solaris的故事
    Solaris 的防火墙ipfilter设置
    mysql安置设置文件的成绩
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/6627083.html
Copyright © 2020-2023  润新知