zoukankan      html  css  js  c++  java
  • 【BZOJ3790】神奇项链(manacher,树状数组)

    题意:

    思路:生成一些回文拼起来使生成的段数最小

    显然存在一种最优的方案,使生成的那些回文是目标串的极长回文子串

    求出对于每个位置的最长回文子串,问题就转化成了:

    给定一些已知起始和终止位置的线段,求覆盖住整个区域的最小线段数量

    这个可以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.
  • 相关阅读:
    安装cifs 访问windows的共享文件
    创建swap文件
    linxu 网路的一些命令
    database mysql
    __alloc_pages
    firefox tips
    关于文件的BOM头
    java实现跳表
    java中如何优雅的停止一个线程
    java中Thread启动流程分析
  • 原文地址:https://www.cnblogs.com/myx12345/p/6710945.html
Copyright © 2011-2022 走看看