zoukankan      html  css  js  c++  java
  • bzoj3238

    都LCP了很显然是要用到后缀数组的

    显然前面的那个东西是可以直接算出来的

    关键在于LCP的和怎么快速的计算

    不难想到穷举height[i],然后判断这个height[i]可能成为多少对后缀的LCP

    考虑到LCP(i,j)=min(height[rank[i]+1~rank[j]]) 假定rank[i]<rank[j];

    假设height[l]是左边第一个小于height[i]的,height[r]是右边第一个小于height[i]的

    则height[i]是(i-l)(r-i)对后缀的LCP

    但这样有一个问题,相同height可能会被重复计算

    为了避免重复,我们定义height[r]是右边第一个不大于height[i]的

    这样就有两种方法来实现

    第一种是二分+rmq,但不幸的是我竟然写超时,而且我觉得容易出错

    第二种是利用单调队列,我们把height[i]对应的l,r定义为左右边界,记为l[i],r[i];

    计算左边界和右边界是相似的,这里我们讨论左边界

    假如height[j]<=height[k] (j>k) 那么对于之后的height[i],

    要么能延伸到k之前(height[i]<=height[j]),要么只能左边界就是j(height[i]>height[j]),不用比较height[k]

    显然我们要维护一个单调不降的队列就行了

    最后计算的时候注意用int64

      1 var rank,sa,y,q,x,sum,h,l,r:array[0..600010] of longint;
      2     s:ansistring;
      3     i,n,m,p,j,t:longint;
      4     ans,z:int64;
      5 
      6 function min(a,b:longint):longint;
      7   begin
      8     if a>b then exit(b) else exit(a);
      9   end;
     10 
     11 procedure suffix;
     12   var i,j,p:longint;
     13   begin
     14     for i:=1 to n do
     15     begin
     16       y[i]:=ord(s[i]);
     17       inc(sum[y[i]]);
     18     end;
     19     m:=255;
     20     for i:=1 to m do
     21       inc(sum[i],sum[i-1]);
     22     for i:=n downto 1 do
     23     begin
     24       sa[sum[y[i]]]:=i;
     25       dec(sum[y[i]]);
     26     end;
     27     p:=1;
     28     rank[sa[1]]:=1;
     29     for i:=2 to n do
     30     begin
     31       if y[sa[i]]<>y[sa[i-1]] then inc(p);
     32       rank[sa[i]]:=p;
     33     end;
     34     m:=p;
     35     j:=1;
     36     while m<n do
     37     begin
     38       fillchar(sum,sizeof(sum),0);
     39       y:=rank;
     40       p:=0;
     41       for i:=n-j+1 to n do
     42       begin
     43         inc(p);
     44         x[p]:=i;
     45       end;
     46       for i:=1 to n do
     47         if sa[i]>j then
     48         begin
     49           inc(p);
     50           x[p]:=sa[i]-j;
     51         end;
     52 
     53       for i:=1 to n do
     54       begin
     55         rank[i]:=y[x[i]];
     56         inc(sum[rank[i]]);
     57       end;
     58       for i:=1 to m do
     59         inc(sum[i],sum[i-1]);
     60       for i:=n downto 1 do
     61       begin
     62         sa[sum[rank[i]]]:=x[i];
     63         dec(sum[rank[i]]);
     64       end;
     65       p:=1;
     66       rank[sa[1]]:=1;
     67       for i:=2 to n do
     68       begin
     69         if (y[sa[i]]<>y[sa[i-1]]) or (y[sa[i]+j]<>y[sa[i-1]+j]) then inc(p);
     70         rank[sa[i]]:=p;
     71       end;
     72       m:=p;
     73       j:=j shl 1;
     74     end;
     75     h[1]:=0;
     76     p:=0;
     77     for i:=1 to n do
     78     begin
     79       if rank[i]=1 then continue;
     80       j:=sa[rank[i]-1];
     81       while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
     82       h[rank[i]]:=p;
     83       if p>0 then dec(p);
     84     end;
     85   end;
     86 
     87 function calc(i,x,y:int64):int64;
     88   begin
     89     exit(2*h[i]*(i-x)*(y-i));
     90   end;
     91 
     92 begin
     93   readln(s);
     94   n:=length(s);
     95   suffix;
     96   z:=n;
     97   ans:=(z+1)*z div 2*(z-1);
     98   t:=0;
     99   for i:=2 to n do
    100   begin
    101     while (t>0) and (h[q[t]]>=h[i]) do dec(t);
    102     if t=0 then l[i]:=1
    103     else l[i]:=q[t];
    104     inc(t);
    105     q[t]:=i;
    106   end;
    107   t:=0;
    108   for i:=n downto 2 do
    109   begin
    110     while (t>0) and (h[q[t]]>h[i]) do dec(t);  //注意右边界是第一个不大于的height,防止重复
    111     if t=0 then r[i]:=n+1
    112     else r[i]:=q[t];
    113     inc(t);
    114     q[t]:=i;
    115   end;
    116   for i:=2 to n do
    117     ans:=ans-calc(i,l[i],r[i]);
    118   writeln(ans);
    119 end.
    View Code
  • 相关阅读:
    deeplearning.ai 卷积神经网络 Week 1 卷积神经网络
    deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II
    deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I
    deeplearning.ai 改善深层神经网络 week3 超参数调试、Batch Normalization和程序框架
    deeplearning.ai 改善深层神经网络 week2 优化算法
    deeplearning.ai 改善深层神经网络 week1 深度学习的实用层面
    cs231n spring 2017 lecture8 Deep Learning Networks
    cs231n spring 2017 lecture7 Training Neural Networks II
    cs231n spring 2017 lecture6 Training Neural Networks I
    cs231n spring 2017 Python/Numpy基础
  • 原文地址:https://www.cnblogs.com/phile/p/4473164.html
Copyright © 2011-2022 走看看