• 字符串(后缀数组):HAOI2016 找相同子串


    [HAOI2016]找相同子串

    【题目描述】

    给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。

    【输入格式】

    两行,两个字符串s1,s2,长度分别为n1,n2

    【输出格式】

    输出一个整数表示答案。

    【样例输入】

    aabb
    bbaa
    

    【样例输出】

    10

    【数据范围】

    对于20%的数据,满足1n1,n2500

    对于40%的数据,满足1n1,n25000

    对于100%的数据,满足1n1,n2200000,字符串中只有小写字母。

      和POJ 3415几乎一样。

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 const int N=400010;
     6 char s[N];int len,d;
     7 int r[N],Wa[N],Wb[N],sa[N],rk[N];
     8 int Ws[N],Wv[N],lcp[N];
     9 
    10 bool cmp(int *p,int i,int j,int l){
    11     return p[i]==p[j]&&p[i+l]==p[j+l];
    12 }
    13 
    14 void DA(int n,int m){
    15     int i,j,p,*x=Wa,*y=Wb;
    16     for(i=0;i<m;i++)Ws[i]=0;
    17     for(i=0;i<n;i++)++Ws[x[i]=r[i]];
    18     for(i=1;i<m;i++)Ws[i]+=Ws[i-1];
    19     for(i=n-1;i>=0;i--)sa[--Ws[x[i]]]=i;
    20     for(j=1,p=1;p<n;j<<=1,m=p){
    21         for(p=0,i=n-j;i<n;i++)y[p++]=i;
    22         for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
    23         for(i=0;i<m;i++)Ws[i]=0;
    24         for(i=0;i<n;i++)++Ws[Wv[i]=x[y[i]]];
    25         for(i=1;i<m;i++)Ws[i]+=Ws[i-1];
    26         for(i=n-1;i>=0;i--)sa[--Ws[Wv[i]]]=y[i];
    27         for(swap(x,y),p=1,x[sa[0]]=0,i=1;i<n;i++)
    28             x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    29     }
    30 }
    31 
    32 void LCP(int n){
    33     int i,j,k=0;
    34     for(i=1;i<=n;i++)rk[sa[i]]=i;
    35     for(i=0;i<n;lcp[rk[i++]]=k)
    36         for(k?k--:k,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
    37 }
    38 
    39 int ID(int x){x=sa[x];
    40     if(x==d)return 0;
    41     if(x<d)return 1;
    42     return 2; 
    43 }
    44 
    45 int st[N]={-1},top;
    46 long long sum[N],tot[N],ans;
    47 int main(){
    48     freopen("find_2016.in","r",stdin);
    49     freopen("find_2016.out","w",stdout);
    50     scanf("%s",s);
    51     len=d=strlen(s);
    52     scanf("%s",s+len+1);
    53     s[d]='#';len=strlen(s);
    54     for(int i=0;i<len;i++)r[i]=s[i];
    55     DA(len+1,128);LCP(len);
    56     for(int i=1;i<=len;i++){
    57         if(!ID(i))continue;
    58         if(ID(i)==2)ans+=tot[top];
    59         if(i!=len){
    60             st[++top]=lcp[i+1];sum[top]=2-ID(i);
    61             tot[top]=st[top]*sum[top]+tot[top-1];
    62             while(st[top]<=st[top-1]){
    63                 sum[top-1]+=sum[top];
    64                 st[top-1]=st[top];top--;
    65                 tot[top]=st[top]*sum[top]+tot[top-1];
    66             }
    67         }
    68     }
    69     top=0;
    70     for(int i=1;i<=len;i++){
    71         if(!ID(i))continue;
    72         if(ID(i)==1)ans+=tot[top];
    73         if(i!=len){
    74             st[++top]=lcp[i+1];sum[top]=ID(i)-1;
    75             tot[top]=st[top]*sum[top]+tot[top-1];
    76             while(st[top]<=st[top-1]){
    77                 sum[top-1]+=sum[top];
    78                 st[top-1]=st[top];top--;
    79                 tot[top]=st[top]*sum[top]+tot[top-1];
    80             }
    81         }
    82     }
    83     printf("%lld
    ",ans);
    84     return 0;
    85 }
  • 相关阅读:
    'live-server' 不是内部或外部命令,也不是可运行的程序 或批处理文件。(解决)
    Node.js安装及环境配置之Windows篇
    开发模式
    IOS13越狱后虚拟定位插件的推荐,relocate
    python,向列表中追加字典,被最后的值覆盖的问题解决办法
    博客园cnblog使用百度统计等站长统计的方法
    IOS解锁哔哩哔哩大会员免费版越狱插件的cydia源
    filza无法安装deb(filza command not found)的解决办法
    Mac 中dock栏图标中文乱码英文正常的解决办法
    关于NVIDIA显卡控制面板中“调整桌面颜色设置”在重启后设置失效的处理方法
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5861085.html
Copyright © 2020-2023  润新知