zoukankan      html  css  js  c++  java
  • bzoj4044

    这题简直了…………

    首先根据操作可知,我们肯定是先造出某个偶数长度的回文串,然后添加若干字符得到设回文串长为len[x]

    则ans=min(n-len[x]+f[x]);

    那么问题就是制造这个串的回文串,最少的操作次数

    对于回文串x,我们有这种情况

    f[x]=min(f[y]+1,(y是x去掉首尾),f[y]+len[x]-len[y](y是最长回文前缀,(其实这个可以不考虑,因为这就相当于直接制造y)

    =(f[y]+len[x] div 2-len[y]+1,y是长度不超过x一半的最长回文后缀)

    dp大家都会,但状态怎么表示呢?………………

    显然一个串回文串不超过n,但是怎么表示之间的关系呢?

    我曾yy了一种manacher+后缀自动机的做法,结果是又WA又T一时爽……

    无奈学了一下回文树,感觉是非常简洁明快的

    学习可以转到:http://pan.baidu.com/s/1hqzRlvm

    感觉有点像ac自动机,还是比较好懂的,这样就简单了

    但我pascal本地AC交上去不停RE不知为何……

      1 var go:array[0..200010,1..4] of longint;
      2     len,fa,sub,a,q,f:array[0..200010] of longint;
      3     last,t,ans,i,tt,n:longint;
      4     s:ansistring;
      5 
      6 function min(a,b:longint):longint;
      7   begin
      8     if a>b then exit(b) else exit(a);
      9   end;
     10 
     11 function what(ch:char):longint;
     12   begin
     13     if ch='A' then exit(1);
     14     if ch='T' then exit(2);
     15     if ch='C' then exit(3);
     16     if ch='G' then exit(4);
     17     exit(-1);
     18   end;
     19 
     20 procedure getchar;
     21   var i:longint;
     22   begin
     23     readln(s);
     24     n:=length(s);
     25     a[n+1]:=-1;
     26     for i:=1 to n do
     27       a[i]:=what(s[i]);
     28   end;
     29 
     30 function getf(x:longint):longint;
     31   begin
     32     while a[i-len[x]-1]<>a[i] do x:=fa[x];
     33     exit(x);
     34   end;
     35 
     36 procedure newnode(l:longint);
     37   begin
     38     inc(t);
     39     fillchar(go[t],sizeof(go[t]),0);
     40     len[t]:=l;
     41     fa[t]:=0;
     42   end;
     43 
     44 procedure add(c:longint);
     45   var now,cur,x:longint;
     46   begin
     47     cur:=getf(last);
     48     if go[cur,c]=0 then
     49     begin
     50       newnode(len[cur]+2); now:=t;
     51       fa[now]:=go[getf(fa[cur]),c];
     52       go[cur,c]:=now;
     53       if len[now]<=2 then f[now]:=len[now]
     54       else begin
     55         x:=sub[cur];
     56         while (a[i-len[x]-1]<>a[i]) or (2*(len[x]+2)>len[now]) or (len[x] mod 2=1) do x:=fa[x];
     57         sub[now]:=go[x,c];
     58       end;
     59     end;
     60     last:=go[cur,c];
     61   end;
     62 
     63 procedure bfs;
     64   var h,r,x,y,i,w:longint;
     65   begin
     66     h:=1;
     67     r:=1;
     68     q[1]:=0;
     69     f[0]:=1;
     70     while h<=r do
     71     begin
     72       x:=q[h];
     73       for i:=1 to 4 do
     74       begin
     75         y:=go[x,i];
     76         if y<>0 then
     77         begin
     78           inc(r);
     79           q[r]:=y;
     80           if len[y]>2 then
     81           begin
     82             f[y]:=min(f[x]+1,len[y] div 2-len[sub[y]]+f[sub[y]]+1);
     83             ans:=min(ans,n-len[y]+f[y]);
     84           end;
     85         end;
     86       end;
     87       inc(h);
     88     end;
     89   end;
     90 
     91 begin
     92   readln(tt);
     93   while tt>0 do
     94   begin
     95     dec(tt);
     96     getchar;
     97     t:=-1;
     98     newnode(0);
     99     newnode(-1);
    100     fa[0]:=1;
    101     last:=0;
    102     for i:=1 to n do
    103       add(a[i]);
    104     ans:=n;
    105     bfs;
    106     writeln(ans);
    107   end;
    108 end.
    View Code
  • 相关阅读:
    js事件分类
    过3s弹出广告条,点叉号关闭
    js进阶
    js入门
    html
    R Markdown + Infinite Moon Reader + 编辑实时更新
    png转ico+windows图标+GIMP
    微生物+计算细胞倍增时间
    使用Mathjax网页插入公式
    Firefox+zoom+全局缩放比例
  • 原文地址:https://www.cnblogs.com/phile/p/4590655.html
Copyright © 2011-2022 走看看