## 【BZOJ3790】神奇项链（manacher，树状数组）

 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
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.

null

posted on 2017-04-14 21:18  myx12345  阅读(140)  评论(0编辑  收藏  举报