安徽师大附中%你赛day6 T3 Hamsters [POI2010]CHO-Hamsters 解题报告

[POI2010]CHO-Hamsters

题意:

给出n个互不包含的字符串,要求你求出一个最短的字符串S,使得这n个字符串在S中总共至少出现m次,问S最短是多少?

范围:

(1 le n le 200,1 le m le 10^9),(sum_S le 100000)


图论模型,矩阵乘法优化floyd

首先虚点连字符串,边权为长度,然后字符串相互连接,边权为后者长度-最长公共部分

前后匹配的方法比较多,hash,kmp,AC自动机都行

然后很容易找到一个floyd的方法

我们利用矩阵快速幂进行优化就行了


Code:

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define ll long long
ll min(ll x,ll y){return x<y?x:y;}
const int N=202;
int n,m;
struct matrix
{
    ll dx[N][N];
    matrix()
    {
        memset(dx,0x3f,sizeof(dx));
    }
    matrix friend operator *(matrix n1,matrix n2)
    {
        matrix n3;
        for(int k=0;k<=n;k++)
            for(int i=0;i<=n;i++)
                for(int j=0;j<=n;j++)
                    n3.dx[i][j]=min(n3.dx[i][j],n1.dx[i][k]+n2.dx[k][j]);
        return n3;
    }
}x,f;
char name[100010];
const ll base=26,mod=19260817;
ll g[N][N],pow[100010];
vector <ll> has[N];
ll get_hash(int id,int l,int r)
{
    return ((has[id][r]-has[id][l-1]*pow[r+1-l])%mod+mod)%mod;
}
ll cal(int i,int j)
{
    int l1=x.dx[0][i],l2=x.dx[0][j];
    for(int k=min(l1,l2)-1;k;k--)
        if(get_hash(i,l1-k+1,l1)==get_hash(j,1,k)) return k;
    return 0;
}
void init()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",name+1);
        int len=strlen(name+1);
        x.dx[0][i]=len;
        has[i].push_back(0);
        for(int j=1;j<=len;j++)
            has[i].push_back(has[i][j-1]*base%mod+name[j]-'a');
    }
    pow[0]=1;
    for(int i=1;i<=100000;i++)
        pow[i]=pow[i-1]*base%mod;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            x.dx[i][j]=x.dx[0][j]-cal(i,j);
}
void work()
{
    --m;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=n;j++)
            f.dx[i][j]=x.dx[i][j];
    while(m)
    {
        if(m&1) f=f*x;
        x=x*x;
        m>>=1;
    }
    ll ans=0x7fffffffffffffffll;
    for(int i=1;i<=n;i++)
        ans=min(ans,f.dx[0][i]);
    printf("%lld
",ans);
}
int main()
{
    init();
    work();
    return 0;
}


2018.8.18

原文地址:https://www.cnblogs.com/butterflydew/p/9498594.html