bzoj2085
首先看到k的范围就该知道这题不是倍增就是矩乘
首先肯定要求出任意一对串(a,b) a的后缀与b的前缀相同的最长长度是多少
考虑到kmp求出的失配指针是一个串最长后缀和前缀相等的长度
这里多个串我们只要用ac自动机即可
具体的,我们只要建立自动机,然后记录每个状态点是哪些串的子串
然后我们只要从每个串的结尾节点出发,顺着失配指针统计即可
然后我们把每个串看作一个点,点之间的边长度就是虽代表串的后缀前缀相同的最长长度
这个问题等价于求经过k条边的最短长度,倍增轻松搞定
const inf=*;
type node=record
po,next:longint;
end;
mtx=array[..,..] of int64; var lcp:array[..,..] of longint;
d,p,w,fa,q:array[..] of longint;
loc:array[..] of longint;
e:array[..*] of node;
trie:array[..,'a'..'z'] of longint;
f,a:mtx;
ss:ansistring;
t,len,i,n,m,j,k:longint;
ans:int64; function min(a,b:int64):int64;
begin
if a>b then exit(b) else exit(a);
end; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure add(x,y:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
p[x]:=len;
end; procedure ac;
var h,r,x,y,j:longint;
c:char;
begin
h:=;
r:=;
for c:='a' to 'z' do
if trie[,c]> then
begin
inc(r);
q[r]:=trie[,c];
end; while h<=r do
begin
x:=q[h];
for c:='a' to 'z' do
if trie[x,c]> then
begin
y:=trie[x,c];
inc(r);
q[r]:=y;
j:=fa[x];
while (j>) and (trie[j,c]=) do j:=fa[j];
fa[y]:=trie[j,c];
end;
inc(h);
end;
end; procedure get(k,x:longint);
var i,j:longint;
begin
while fa[x]<> do
begin
x:=fa[x];
i:=p[x];
while i<> do
begin
j:=e[i].po;
lcp[k,j]:=max(lcp[k,j],d[x]);
i:=e[i].next;
end;
end;
end; procedure mul(var c:mtx; a,b:mtx);
var i,j,k:longint;
begin
for i:= to n do
for j:= to n do
c[i,j]:=inf; for k:= to n do
for i:= to n do
for j:= to n do
c[i,j]:=min(c[i,j],a[i,k]+b[k,j]);
end; begin
readln(n,m);
for i:= to n do
begin
readln(ss);
w[i]:=length(ss);
j:=;
for k:= to w[i] do
begin
if trie[j,ss[k]]= then
begin
inc(t);
trie[j,ss[k]]:=t;
end;
j:=trie[j,ss[k]];
d[j]:=k;
add(j,i);
end;
loc[i]:=j;
end;
ac;
for i:= to n do
get(i,loc[i]);
for i:= to n do
for j:= to n do
a[i,j]:=w[j]-lcp[i,j]; for i:= to n do
for j:= to n do
if i<>j then f[i,j]:=inf;
dec(m);
while m> do
begin
if m mod = then mul(f,f,a);
m:=m shr ;
mul(a,a,a);
end;
ans:=inf;
for i:= to n do
for j:= to n do
ans:=min(ans,f[i,j]+w[i]);
writeln(ans);
end.
bzoj2085的更多相关文章
- BZOJ2085 : [Poi2010]Hamsters
设g[i][j]为i串至少加上几个字符后才能包含j,可以通过Hash求出. 然后就是求经过m-1条边的最短路,用倍增加速Floyed即可,时间复杂度$O(n^3\log m)$. #include&l ...
- 【bzoj2085】[Poi2010]Hamsters Hash+倍增Floyd
题目描述 Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多少个名字,请你求出最 ...
- bzoj2085 [Poi2010]Hamsters 矩阵快速幂+字符串hash
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2085 题解 考虑暴力 DP 的做法.令 \(dp[i][j]\) 表示以 \(j\) 为开头的 ...
- BZOJ 2085 [POI2010] Hamsters
题面 Description Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多 ...
- 倍增&矩阵乘法 专题复习
倍增&矩阵乘法 专题复习 PreWords 这两个基础算法我就不多说啦,但是还是要介绍一下" 广义矩阵 "乘法 其实就是把矩阵换成取\(max\),然后都一样... 据神仙 ...
随机推荐
- 特征值分解,奇异值分解(SVD)
特征值分解和奇异值分解在机器学习领域都是属于满地可见的方法.两者有着很紧密的关系,我在接下来会谈到,特征值分解和奇异值分解的目的都是一样,就是提取出一个矩阵最重要的特征. 1. 特征值: 如果说一个向 ...
- MITK Tutorial(二)
目标: 生成MITK 插件包括一个新用户交互的视图,并调用一些ITK filters. Step 1: How to create a new MITK Plugin 可以选择用Plugin Gene ...
- HTML5 本地裁剪图片
下面奉上我自己写的一个demo,代码写得比较少,很多细节不会处理.如果有不得当的地方恳请指教,谢谢啦 ^_^ ^_^ 功能实现步奏: 一:获取文件,读取文件并生成url 二:根据容器的大小 ...
- 【BZOJ】【2179】FFT快速傅里叶
FFT 做的第二道用到FFT的……好吧其实还是模板题-_-b 百度上说好像分治也能做……不过像FFT这种敲模板的还是省事=.= /*********************************** ...
- oracle——表修改语句集合
alter table table_name modify column_name default 0;
- 【ACMER纷纷表示】女生应该找一个玩ACM的男生
1.强烈的事业心 将来,他也一定会有自己热爱的事业.而且,男人最性感的时刻之一,就是他专心致志做事的时候.所以,找一个机会在他全神贯注玩ACM的时候,从侧面好好观察他,你就会发现我说的话没错.2.永不 ...
- wordpress数据库优化wp_posts表 OPTIMIZE
wordpress数据库优化wp_posts表 对 MySQL 数据记录进行插入.更新或删除时,会占有不同大小的空间,记录就会变成碎片,且留下空闲的空间.就像具有碎片的磁盘,会降低性能,需要整理,因此 ...
- Openstack Quantum project 更名为 Neuron
因为与磁带备份厂商Quantum商标冲突: The OpenStack Foundation has changed the name of its networking project from Q ...
- OneAPM 技术公开课第二讲:开启性能为王的架构时代
「OneAPM 技术公开课」由应用性能管理第一品牌 OneAPM 发起,内容面向 IT 开发和运维人员.云集技术牛人.知名架构师.实践专家共同探讨技术热点.继北京站第一场火爆上演之后,第二场将于9月1 ...
- SDUT1591交叉排序
http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=1591&cid=1187 #include<cstdio> #include& ...