bzoj2085

首先看到k的范围就该知道这题不是倍增就是矩乘

首先肯定要求出任意一对串(a,b) a的后缀与b的前缀相同的最长长度是多少

考虑到kmp求出的失配指针是一个串最长后缀和前缀相等的长度

这里多个串我们只要用ac自动机即可

具体的,我们只要建立自动机,然后记录每个状态点是哪些串的子串

然后我们只要从每个串的结尾节点出发,顺着失配指针统计即可

然后我们把每个串看作一个点,点之间的边长度就是虽代表串的后缀前缀相同的最长长度

这个问题等价于求经过k条边的最短长度,倍增轻松搞定

  1 const inf=2147483647*2147483647;
  2 type node=record
  3        po,next:longint;
  4      end;
  5      mtx=array[0..201,0..201] of int64;
  6 
  7 var lcp:array[0..201,0..201] of longint;
  8     d,p,w,fa,q:array[0..100010] of longint;
  9     loc:array[0..201] of longint;
 10     e:array[0..100010*200] of node;
 11     trie:array[0..100010,'a'..'z'] of longint;
 12     f,a:mtx;
 13     ss:ansistring;
 14     t,len,i,n,m,j,k:longint;
 15     ans:int64;
 16 
 17 function min(a,b:int64):int64;
 18   begin
 19     if a>b then exit(b) else exit(a);
 20   end;
 21 
 22 function max(a,b:longint):longint;
 23   begin
 24     if a>b then exit(a) else exit(b);
 25   end;
 26 
 27 procedure add(x,y:longint);
 28   begin
 29     inc(len);
 30     e[len].po:=y;
 31     e[len].next:=p[x];
 32     p[x]:=len;
 33   end;
 34 
 35 procedure ac;
 36   var h,r,x,y,j:longint;
 37       c:char;
 38   begin
 39     h:=1;
 40     r:=0;
 41     for c:='a' to 'z' do
 42       if trie[0,c]>0 then
 43       begin
 44         inc(r);
 45         q[r]:=trie[0,c];
 46       end;
 47 
 48     while h<=r do
 49     begin
 50       x:=q[h];
 51       for c:='a' to 'z' do
 52         if trie[x,c]>0 then
 53         begin
 54           y:=trie[x,c];
 55           inc(r);
 56           q[r]:=y;
 57           j:=fa[x];
 58           while (j>0) and (trie[j,c]=0) do j:=fa[j];
 59           fa[y]:=trie[j,c];
 60         end;
 61       inc(h);
 62     end;
 63   end;
 64 
 65 procedure get(k,x:longint);
 66   var i,j:longint;
 67   begin
 68     while fa[x]<>0 do
 69     begin
 70       x:=fa[x];
 71       i:=p[x];
 72       while i<>0 do
 73       begin
 74         j:=e[i].po;
 75         lcp[k,j]:=max(lcp[k,j],d[x]);
 76         i:=e[i].next;
 77       end;
 78     end;
 79   end;
 80 
 81 procedure mul(var c:mtx; a,b:mtx);
 82   var i,j,k:longint;
 83   begin
 84     for i:=1 to n do
 85       for j:=1 to n do
 86         c[i,j]:=inf;
 87 
 88     for k:=1 to n do
 89       for i:=1 to n do
 90         for j:=1 to n do
 91           c[i,j]:=min(c[i,j],a[i,k]+b[k,j]);
 92   end;
 93 
 94 begin
 95   readln(n,m);
 96   for i:=1 to n do
 97   begin
 98     readln(ss);
 99     w[i]:=length(ss);
100     j:=0;
101     for k:=1 to w[i] do
102     begin
103       if trie[j,ss[k]]=0 then
104       begin
105         inc(t);
106         trie[j,ss[k]]:=t;
107       end;
108       j:=trie[j,ss[k]];
109       d[j]:=k;
110       add(j,i);
111     end;
112     loc[i]:=j;
113   end;
114   ac;
115   for i:=1 to n do
116     get(i,loc[i]);
117   for i:=1 to n do
118     for j:=1 to n do
119       a[i,j]:=w[j]-lcp[i,j];
120 
121   for i:=1 to n do
122     for j:=1 to n do
123       if i<>j then f[i,j]:=inf;
124   dec(m);
125   while m>0 do
126   begin
127     if m mod 2=1 then mul(f,f,a);
128     m:=m shr 1;
129     mul(a,a,a);
130   end;
131   ans:=inf;
132   for i:=1 to n do
133     for j:=1 to n do
134       ans:=min(ans,f[i,j]+w[i]);
135   writeln(ans);
136 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4533451.html