zoukankan      html  css  js  c++  java
  • [后缀数组] Luogu P5028 Annihilate

    题目描述

    黑暗之主的蜈蚣几乎可以毁灭一切,因此小正方形陷入了苦战……

    小正方形现在需要减弱黑暗之主的攻击。

    一个黑暗之主的攻击可以用一个仅有小写字母的字符串表示。

    现在黑暗之主向小正方形发动了若干攻击,对于两个攻击,小正方形能选出它们最长的公共子串,并把这一段消除。

    现在小正方形想要知道,对于任意两个黑暗之主的攻击,它们的最长公共子串长度是多少,你能帮帮它吗?

    题解

    • 先把所有的字符串拼起来,每两个之间用个奇奇怪怪的字符隔出,然后就跑SA
    • 题目要求是要求最长公共字串,我们要找的是最长的,又因为ans是一段height的min,所以肯定找最近的
    • 于是,pre[i]不再维护位置了,维护最近一次出现的位置到当前的min(height)就行了

    代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #define N 2000010 
     5 #define M 60 
     6 using namespace std;
     7 int n,l,m=600,t[N],x[N],c[N],sa[N],bel[N],height[N],rank[N],pre[M],len[M],ans[M][M];
     8 char s[N];
     9 void get_SA()
    10 {
    11     l=len[n]+1;
    12     for (int i=1;i<=l;i++) c[x[i]=s[i]]++;
    13     for (int i=2;i<=m;i++) c[i]+=c[i-1];
    14     for (int i=l;i>=1;i--) sa[c[x[i]]--]=i;
    15     for (int k=1;k<=l;k<<=1)
    16     {
    17         int p=0;
    18         for (int i=l-k+1;i<=l;i++) t[++p]=i;
    19         for (int i=1;i<=l;i++) if (sa[i]>k) t[++p]=sa[i]-k;
    20         for (int i=1;i<=m;i++) c[i]=0;
    21         for (int i=1;i<=l;i++) c[x[i]]++;
    22         for (int i=2;i<=m;i++) c[i]+=c[i-1];
    23         for (int i=l;i>=1;i--) sa[c[x[t[i]]]--]=t[i],t[i]=0;
    24         swap(x,t);
    25         p=1,x[sa[1]]=1;
    26         for (int i=2;i<=l;i++) x[sa[i]]=(t[sa[i-1]]==t[sa[i]]&&t[sa[i-1]+k]==t[sa[i]+k])?p:++p; 
    27         if (p==l) break;
    28         m=p;
    29     }
    30     int k=0;
    31     for (int i=1;i<=l;i++) rank[sa[i]]=i;
    32     for (int i=1;i<=l;i++)  
    33     {
    34         if (rank[i]==1) continue;
    35         if (k) k--;
    36         int j=sa[rank[i]-1];
    37         while (j+k<=l&&i+k<=l&&s[i+k]==s[j+k]) k++;
    38         height[rank[i]]=k;
    39     }
    40 }
    41 int main()
    42 {
    43     scanf("%d",&n),len[0]=-1;
    44     for (int i=1;i<=n;i++)
    45     {
    46         char ch;
    47         while (!isalpha(ch=getchar()));
    48         for (len[i]=len[i-1]+1,s[++len[i]]=ch,bel[len[i]]=i;isalpha(ch=getchar());s[++len[i]]=ch,bel[len[i]]=i);
    49         s[len[i]+1]=300+i; 
    50     }
    51     get_SA();
    52     for (int i=2;i<=l;i++)
    53     {
    54         for (int j=1;j<=n;j++) pre[j]=min(pre[j],height[i]);
    55         int b=bel[sa[i]]; pre[bel[sa[i-1]]]=height[i];
    56         if (!b) continue;
    57         for (int j=1;j<=n;j++) ans[j][b]=ans[b][j]=max(ans[b][j],pre[j]);
    58     }
    59     for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) if (i!=j) printf("%d ",ans[i][j]); printf("
    "); } 
    60 }
  • 相关阅读:
    HTML5结构
    HTML5新增的非主体元素header元素、footer元素、hgroup元素、adress元素
    CF GYM 100703G Game of numbers
    CF GYM 100703I Endeavor for perfection
    CF GYM 100703K Word order
    CF GYM 100703L Many questions
    CF GYM 100703M It's complicate
    HDU 5313 Bipartite Graph
    CF 560e Gerald and Giant Chess
    POJ 2479 Maximum sum
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11262089.html
Copyright © 2011-2022 走看看