# bzoj3790

  1 var s:array[0..100010] of char;
2     c,l,r,f,p:array[0..100010] of longint;
3     i,j,t,n,m,ans,k,right:longint;
4     ch:char;
5
6 procedure swap(var a,b:longint);
7   var c:longint;
8   begin
9     c:=a;
10     a:=b;
11     b:=c;
12   end;
13
14 function min(a,b:longint):longint;
15   begin
16     if a>b then exit(b) else exit(a);
17   end;
18
19 function lowbit(x:longint):longint;
20   begin
21     exit(x and (-x));
22   end;
23
24 procedure sort(ll,rr: longint);
25   var i,j,x,y: longint;
26   begin
27     i:=ll;
28     j:=rr;
29     x:=r[(ll+rr) shr 1];
30     y:=l[(ll+rr) shr 1];
31     repeat
32       while (r[i]<x) or (r[i]=x) and (l[i]<y) do inc(i);
33       while (x<r[j]) or (r[j]=x) and (y<l[j]) do dec(j);
34       if not(i>j) then
35       begin
36         swap(r[i],r[j]);
37         swap(l[i],l[j]);
38         inc(i);
39         j:=j-1;
40       end;
41     until i>j;
42     if ll<j then sort(ll,j);
43     if i<rr then sort(i,rr);
44   end;
45
47   begin
48     if x=0 then exit(0);
50     while x<=n do  //因为求的是后缀最小值，事实上只要将查询和修改的范围换一下即可
51     begin
53       x:=x+lowbit(x);
54     end;
55   end;
56
58   var x:longint;
59   begin
60     x:=r[i];
61     while x>0 do
62     begin
63       c[x]:=min(c[x],f[i]);
64       x:=x-lowbit(x);
65     end;
66   end;
67
68 begin
69   while true do
70   begin
72     if not((ch>='a') and (ch<='z')) then break;
73     s[0]:='\$';
74     s[1]:='#';
75     m:=1;
76     n:=0;
77     while (ch>='a') and (ch<='z') do
78     begin
79       inc(n);
80       inc(m);
81       s[m]:=ch;
82       inc(m);
83       s[m]:='#'; //将回文串的奇偶转化为一种情况
85     end;
86     s[m+1]:=' ';
88     k:=0;
89     right:=0;
90     t:=0;
91     fillchar(p,sizeof(p),0);
92     for i:=1 to m do
93     begin
94       if right>i then   //manacher的核心
95         p[i]:=min(p[2*k-i],right-i)
96       else p[i]:=1;
97       while s[i+p[i]]=s[i-p[i]] do inc(p[i]);
98       if p[i]+i>right then
99       begin
100         right:=p[i]+i;
101         k:=i;
102       end;
103       if (s[i]='#') and (p[i]=1) then continue
104       else begin
105         inc(t);
106         l[t]:=(i-p[i]+2) div 2;
107         r[t]:=(i+p[i]-2) div 2;
108       end;
109     end;
110     sort(1,t);  //解决区间覆盖问题，右端点排序
111     ans:=n;
112     for i:=1 to n do
113       c[i]:=n+1;
114     for i:=1 to t do
115     begin
122 end.