2752这是一道关于next函数的题
(其实好像也可以用后缀数组暴力搞搞,但大概会超时)
根据next[i]=max{j} (s[0..j]=s[i-j..i] j<i)
不难发现这正是某个串既是前缀又是后缀的形式
所以我们先求一遍kmp,然后就是找出所有这样的串
首先最长的肯定是原串,,次长的肯定是s[0..next[n]]
那下一个呢?答案是只要一直从n按着next迭代下去就能找到可行解。
我们不妨设next[i]=j next[j]=k,当i是可行解,那j一定也是
因为s[0..j]=s[i-j..i]可得s[0..k]=s[i-k..k]=s[i-k,i]
然后就解决了
bzoj3670是今年的noi题,其实也是一样的,只不过多了不能重叠,其实也是很好解决的
1 code:poj2752 2 3 var next,q:array[0..400010] of longint; 4 i,j,n,t :longint; 5 s:array[0..400010] of char; 6 ch:ansistring; 7 8 begin 9 while not eof do 10 begin 11 readln(ch); 12 n:=length(ch); 13 for i:=0 to n-1 do 14 s[i]:=ch[i+1]; 15 i:=0; 16 j:=-1; 17 next[0]:=-1; 18 while (i<n) do 19 begin 20 if (j=-1) or (s[i]=s[j]) then 21 begin 22 inc(i); 23 inc(j); 24 next[i]:=j; 25 end 26 else j:=next[j]; 27 end; 28 t:=0; 29 j:=n; 30 while j<>0 do 31 begin 32 inc(t); 33 q[t]:=next[j]; 34 j:=next[j]; 35 end; 36 for i:=t-1 downto 1 do 37 write(q[i],' '); 38 writeln(n); 39 end; 40 end.
1 const mo=1000000007; 2 3 var f,next:array[0..1000010] of longint; 4 a:array[0..1000010] of char; 5 k,n,t,i,j:longint; 6 ans:int64; 7 s:ansistring; 8 9 begin 10 readln(k); 11 while k>0 do 12 begin 13 dec(k); 14 readln(s); 15 n:=length(s); 16 for i:=1 to n do 17 a[i-1]:=s[i]; 18 i:=0; 19 j:=-1; 20 next[0]:=-1; 21 ans:=1; 22 while i<n do 23 begin 24 if (j=-1) or (a[i]=a[j]) then 25 begin 26 inc(i); 27 inc(j); 28 next[i]:=j; 29 f[i]:=f[j]+1; 30 end 31 else j:=next[j]; 32 end; 33 i:=0; 34 j:=-1; 35 while i<n do 36 begin 37 if (j=-1) or (a[i]=a[j]) then 38 begin 39 inc(i); 40 inc(j); 41 while (j*2>i) do j:=next[j]; 42 ans:=ans*int64(f[j]+1) mod mo; 43 end 44 else j:=next[j]; 45 end; 46 writeln(ans); 47 end; 48 end.