标签:int 回文 min lowbit 拓展 put adl bsp har
题意:
思路:生成一些回文拼起来使生成的段数最小
显然存在一种最优的方案,使生成的那些回文是目标串的极长回文子串
求出对于每个位置的最长回文子串,问题就转化成了:
给定一些已知起始和终止位置的线段,求覆盖住整个区域的最小线段数量
这个可以BIT做,求当前已经覆盖的区域最远能拓展到哪里
也可以预处理一下前缀最小值,跳转时直接调用即可
1 const oo=1000000000; 2 var t,a,x,y,p:array[1..110000]of longint; 3 len,n,i,id,mx,ans,m:longint; 4 ch:ansistring; 5 6 function lowbit(x:longint):longint; 7 begin 8 exit(x and (-x)); 9 end; 10 11 function max(x,y:longint):longint; 12 begin 13 if x>y then exit(x); 14 exit(y); 15 end; 16 17 function min(x,y:longint):longint; 18 begin 19 if x<y then exit(x); 20 exit(y); 21 end; 22 23 procedure update(x,y:longint); 24 begin 25 while x<=n-2 do 26 begin 27 t[x]:=max(t[x],y); 28 x:=x+lowbit(x); 29 end; 30 end; 31 32 function query(x:longint):longint; 33 begin 34 query:=-oo; 35 while x>0 do 36 begin 37 query:=max(query,t[x]); 38 x:=x-lowbit(x); 39 end; 40 end; 41 42 begin 43 assign(input,‘bzoj3790.in‘); reset(input); 44 assign(output,‘bzoj3790.out‘); rewrite(output); 45 while not eof do 46 begin 47 readln(ch); 48 len:=length(ch); 49 if len=0 then break; 50 fillchar(a,sizeof(a),0); 51 fillchar(p,sizeof(p),0); 52 n:=2; a[1]:=27; a[2]:=28; 53 for i:=1 to len do 54 begin 55 inc(n); a[n]:=ord(ch[i])-ord(‘a‘)+1; 56 inc(n); a[n]:=28; 57 end; 58 inc(n); a[n]:=29; 59 mx:=0; id:=1; 60 for i:=2 to n-1 do 61 begin 62 if mx>i then p[i]:=min(p[id*2-i],mx-i) 63 else p[i]:=1; 64 while a[i-p[i]]=a[i+p[i]] do inc(p[i]); 65 if p[i]+i>mx then 66 begin 67 mx:=p[i]+i; id:=i; 68 end; 69 end; 70 for i:=1 to m do 71 begin 72 x[i]:=0; y[i]:=0; 73 end; 74 m:=0; 75 for i:=2 to n-1 do 76 begin 77 inc(m); x[m]:=i-p[i]; y[m]:=i+p[i]-2; 78 end; 79 fillchar(t,sizeof(t),0); 80 for i:=1 to m do update(x[i],y[i]); 81 i:=1; ans:=0; 82 while i<n-2 do 83 begin 84 i:=query(i+1); 85 inc(ans); 86 end; 87 writeln(ans-1); 88 end; 89 close(input); 90 close(output); 91 end.
标签:int 回文 min lowbit 拓展 put adl bsp har
原文地址:http://www.cnblogs.com/myx12345/p/6710945.html