题目描述

Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算。现在Tz想好了要出现多少个名字,请你求出最短的字母序列的长度是多少。n个字符串保证不互相包含。

输入

输入:第一行n(1<=n<=200)和m(1<=m<=10的9此方),n表示有多少个仓鼠,m表示Tz希望出现名字的次数,接下来n行,每行都是仓鼠的名字(中间没有空格)。

输出

输出:一行,最短的字母序列的长度。

样例输入

4 5
monika
tomek
szymon
bernard

样例输出

23


题解

Hash+倍增Floyd

由于n只有200,并且任意两串不包含。所以可以预处理出某个串后还需要加几个字符可以变成另一个串,可以使用Hash解决。

然后题目要求出现总数为m,相当于要经过m-1个点的最短路径,使用倍增Floyd快速幂求出。

最后的答案为 原串长+最短路 的最小值。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
char str[100010];
ull hash[100010] , base[100010];
int lp[210] , rp[210] , n;
struct data
{
ull v[210][210];
data() {memset(v , 0x3f , sizeof(v));}
data operator*(const data &a)const
{
data ans;
int i , j , k;
for(k = 1 ; k <= n ; k ++ )
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
ans.v[i][j] = min(ans.v[i][j] , v[i][k] + a.v[k][j]);
return ans;
}
}a , ret;
data pow(data x , int y)
{
data ans;
int i;
for(i = 1 ; i <= n ; i ++ ) ans.v[i][i] = 0;
while(y)
{
if(y & 1) ans = ans * x;
x = x * x , y >>= 1;
}
return ans;
}
int main()
{
int m , i , j , k;
ull ans = 1ull << 63;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
lp[i] = rp[i - 1] + 1 , scanf("%s" , str + lp[i]) , rp[i] = strlen(str + lp[i]) + lp[i] - 1;
base[0] = 1;
for(i = 1 ; i <= rp[n] ; i ++ )
base[i] = base[i - 1] * 2333 , hash[i] = hash[i - 1] * 2333 + str[i];
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
for(k = 0 ; k < rp[i] - lp[i] + 1 && k < rp[j] - lp[j] + 1 ; k ++ )
if(hash[rp[i]] - hash[rp[i] - k] * base[k] == hash[lp[j] + k - 1] - hash[lp[j] - 1] * base[k])
a.v[i][j] = rp[j] - lp[j] + 1 - k;
ret = pow(a , m - 1);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
ans = min(ans , rp[i] - lp[i] + 1 + ret.v[i][j]);
printf("%llu\n" , ans);
return 0;
}

【bzoj2085】[Poi2010]Hamsters Hash+倍增Floyd的更多相关文章

  1. BZOJ 2085 luogu P3502 [POI2010]Hamsters (KMP、Floyd、倍增)

    数组开小毁一生-- 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2085 这题在洛谷上有个条件是"互不包含",其实 ...

  2. bzoj2085 [Poi2010]Hamsters 矩阵快速幂+字符串hash

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2085 题解 考虑暴力 DP 的做法.令 \(dp[i][j]\) 表示以 \(j\) 为开头的 ...

  3. BZOJ2085 : [Poi2010]Hamsters

    设g[i][j]为i串至少加上几个字符后才能包含j,可以通过Hash求出. 然后就是求经过m-1条边的最短路,用倍增加速Floyed即可,时间复杂度$O(n^3\log m)$. #include&l ...

  4. 【CF461E】Appleman and a Game 倍增floyd

    [CF461E]Appleman and a Game 题意:你有一个字符串t(由A,B,C,D组成),你还需要构造一个长度为n的字符串s.你的对手需要用t的子串来拼出s,具体来说就是每次找一个t的子 ...

  5. 2018.11.09 bzoj4773: 负环(倍增+floyd)

    传送门 跟上一道题差不多. 考虑如果环上点的个数跟最短路长度有单调性那么可以直接上倍增+floyd. 然而并没有什么单调性. 于是我们最开始给每个点初始化一个长度为0的自环,于是就有单调性了. 代码: ...

  6. 2018.11.09 bzoj1706: relays 奶牛接力跑(倍增+floyd)

    传送门 倍增+floyd板子题. 先列出状态fi,j,kf_{i,j,k}fi,j,k​表示经过iii条边从jjj到kkk的最短路. 然后发现可以用fi−1,j,kf_{i-1,j,k}fi−1,j, ...

  7. BZOJ.4180.字符串计数(后缀自动机 二分 矩阵快速幂/倍增Floyd)

    题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设 ...

  8. BZOJ4773: 负环(倍增Floyd)

    题意 题目链接 Sol 倍增Floyd,妙妙喵 一个很显然的思路(然而我想不到是用\(f[k][i][j]\)表示从\(i\)号点出发,走\(k\)步到\(j\)的最小值 但是这样复杂度是\(O(n^ ...

  9. bzoj2165: 大楼(倍增floyd)

    题目大意:一个有向图,n(<=100)个点求一条长度>=m(<=10^18)的路径最少经过几条边. 一开始以为是矩乘,蓝鹅当时还没开始写,所以好像给CYC安利错了嘿嘿嘿QWQ 第一眼 ...

随机推荐

  1. 洛谷 P2176 [USACO14FEB]路障Roadblock

    题目描述 每天早晨,FJ从家中穿过农场走到牛棚.农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度.FJ 的房子在 1 号田,牛棚在 N 号田.没有两块田被多条道路连接,以适当的路 ...

  2. 如果不需要,建议移除net standard类库中的Microsoft.NETCore.Portable.Compatibility

    使用Microsoft.NETCore.Portable.Compatibility会破坏该类库在Mono和Xamarin平台的兼容性 可能导致的问题 provides a compile-time ...

  3. 11gR2 Agent 简介

    目的:本文会对oracle 11gR2 集群件(Grid Infrastructure,以下简称GI) 新特性 agent进行介绍,包括 agent的功能,常见的agent介绍,以及基本的诊断方法. ...

  4. 简易数据分析 02 | Web Scraper 的下载与安装

    这是简易数据分析系列的第 2 篇文章. 上篇说了数据分析在生活中的重要性,从这篇开始,我们就要进入分析的实战内容了.数据分析数据分析,没有数据怎么分析?所以我们首先要学会采集数据. 我调研了很多采集数 ...

  5. Java中的集合Collection接口

    /* 集合:集合是存储对象数据的集合容器.集合比数组的优势: 1. 集合可以存储任意类型的对象数据,数组只能存储同一种数据类型 的数据. 2. 集合的长度是会发生变化的,数组的长度是固定的.----- ...

  6. vue 报错unknown custom element解决方法

    原因: 没有引入相关组件导致的 解决办法: 如果组件是按需引入的必须引入你当前用到的组件,否则会报错

  7. MySQL数据库的多种备份与多种还原

    一.备份 1.mysqldump 方法备份 mysqldump备份很简单,格式如下: mysqldump -u用户名 -p密码 数据库名> XX.sql 路径 例如: mysqldump -ur ...

  8. LVS-nat模式-原理介绍

    集群,为解决某个特定问题将多台计算机组合起来形成的单个系统 lvs-nat: 本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发 lvs集群类 ...

  9. PHP redis使用命令

    很有用;以下是redis官方提供的命令使用技巧: 下载地址如下: https://github.com/owlient/phpredis(支持redis 2.0.4) Redis::__constru ...

  10. Python之路--序列化

    序列化的目的 1.以某种存储形式使自定义对象持久化 2.将对象从一个地方传递到另一个地方 3.使程序更具有维护性 json json多语言通用 四个功能:dumps.dump.loads.load # ...