2085: [Poi2010]Hamsters hash+倍增floyd

定义 fk,i,j 表示由第 i 个字符串开头第 j 个字符串结尾且一共有 2k+1 个子串的最短长度,然后倍增floyd转移一下。

#include<iostream>
#include<cstdio>
#include<cstring>
#define U unsigned long long 
#define ll long long 
#define N 205
#define L 100005
#define base 233
#define inf 1e18
using namespace std;
U T[L],hash[N][L];
int len[N];
ll f[32][N][N],A[N][N],B[N][N];
int n,m;
char s[L];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline ll calc(int i,int j)
{
    int MAXN;
    if (i==j) MAXN=len[i]-1;
    else MAXN=min(len[i],len[j]);
    for (int k=MAXN;~k;k--)
        if (hash[i][len[i]]-hash[i][len[i]-k]*T[k]==hash[j][k]) return len[j]-k;
}
int main()
{
    n=read(); m=read()-1; T[0]=1;
    for (int i=1;i<L;i++) T[i]=T[i-1]*base;
    for (int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        len[i]=strlen(s+1);
        for (int j=1;j<=len[i];j++)
            hash[i][j]=hash[i][j-1]*base+s[j];
    }
    memset(f,0x3f,sizeof(f));
    for (int i=1;i<=n;i++)  
        for (int j=1;j<=n;j++)
            f[0][i][j]=calc(i,j);
    for (int p=1;(1<<p)<=m;p++)
        for (int k=1;k<=n;k++)
            for (int i=1;i<=n;i++)
                for (int j=1;j<=n;j++)  
                    f[p][i][j]=min(f[p][i][j],f[p-1][i][k]+f[p-1][k][j]);
    int bit=0;
    for (;(1<<bit)<=m;bit++)
        if ((1<<bit)&m)
        {
            memcpy(A,f[bit],sizeof(A));
            break;
        }
    for (bit++;(1<<bit)<=m;bit++)
        if ((1<<bit)&m)
        {
            memset(B,0x3f,sizeof(B));
            for (int k=1;k<=n;k++)
                for (int i=1;i<=n;i++)
                    for (int j=1;j<=n;j++)
                        B[i][j]=min(B[i][j],min(A[i][k]+f[bit][k][j],f[bit][i][k]+A[k][j]));
            memcpy(A,B,sizeof(A));
        }
    ll ans=inf;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            ans=min(ans,(ll)len[i]+A[i][j]);
    cout << ans << endl;
    return 0;
}   

你可能感兴趣的:(2085: [Poi2010]Hamsters hash+倍增floyd)