zoukankan      html  css  js  c++  java
  • bzoj4566 [Haoi2016]找相同字符

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=4566

    题目:

    4566: [Haoi2016]找相同字符

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 600  Solved: 329

    Description

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

    Input

    两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母

    Output

    输出一个整数表示答案

    Sample Input

    aabb
    bbaa

    Sample Output

    10
     
    思路:
      对第一个串建立后缀自动机,然后让第二个串在sam上跑。
      对于每个走到的状态p,fa[p]状态代表的后缀集合必然出现过,且p状态的长度为now-len[fa[p]](now为走到该状态的匹配长度)
      对于状态p,如果endpos(p)内的后缀全部出现过,则贡献为|endpos(p)|*(len[p]-len[fa[p]]),且要用fa[p]去更新p.
      把每个点的贡献记为sum[p]。
      则走到状态p,ans+=sum[fa[p]]+|endpos(p)|*(now-len[fa])。
     1 /**************************************************************
     2     Problem: 4566
     3     User: weeping
     4     Language: C++
     5     Result: Accepted
     6     Time:2072 ms
     7     Memory:50120 kb
     8 ****************************************************************/
     9  
    10 #include <bits/stdc++.h>
    11  
    12 using namespace std;
    13  
    14 struct SAM
    15 {
    16     static const int MAXN = 200002<<1;//大小为字符串长度两倍
    17     static const int LetterSize = 26;
    18  
    19     int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
    20     int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组
    21  
    22     void init( void)
    23     {
    24         last = tot = 1;
    25         len[1] = 0;
    26         memset(ch,0,sizeof ch);
    27         memset(fa,0,sizeof fa);
    28         memset(cnt,0,sizeof cnt);
    29     }
    30  
    31     void add( int x)
    32     {
    33         int p = last, np = last = ++tot;
    34         len[np] = len[p] + 1, cnt[last] = 1;
    35         while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
    36         if( p == 0)
    37             fa[np] = 1;
    38         else
    39         {
    40             int q = ch[p][x];
    41             if( len[q] == len[p] + 1)
    42                 fa[np] = q;
    43             else
    44             {
    45                 int nq = ++tot;
    46                 memcpy( ch[nq], ch[q], sizeof ch[q]);
    47                 len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
    48                 while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
    49             }
    50         }
    51     }
    52  
    53     void toposort( void)
    54     {
    55         for(int i = 1; i <= len[last]; i++)   sum[i] = 0;
    56         for(int i = 1; i <= tot; i++)   sum[len[i]]++;
    57         for(int i = 1; i <= len[last]; i++)   sum[i] += sum[i-1];
    58         for(int i = 1; i <= tot; i++)   tp[sum[len[i]]--] = i;
    59         for(int i = tot; i; i--)   cnt[fa[tp[i]]] += cnt[tp[i]];
    60     }
    61  
    62     void work(char *ss)
    63     {
    64         long long ans=0;
    65         for(int i = 1; i <= tot; i++)
    66             sum[tp[i]]=sum[fa[tp[i]]]+cnt[tp[i]]*(len[tp[i]]-len[fa[tp[i]]]);
    67         for(int i=0,n=strlen(ss),p=1,num=0;i<n;i++)
    68         {
    69             int c=ss[i]-'a';
    70             if(ch[p][c])    p=ch[p][c],num++;
    71             else
    72             {
    73                 while(p&&!ch[p][c]) p=fa[p];
    74                 if(!p)  p=1,num=0;
    75                 else    num=len[p]+1,p=ch[p][c];
    76             }
    77             ans+=sum[fa[p]]+1LL*cnt[p]*(num-len[fa[p]]);
    78         }
    79         printf("%lld
    ",ans);
    80     }
    81 } sam;
    82  
    83 char sa[200005],sb[200005];
    84  
    85 int main( void)
    86 {
    87     scanf("%s%s",sa,sb);
    88     sam.init();
    89     for(int i=0,len=strlen(sa);i<len;i++)   sam.add(sa[i]-'a');
    90     sam.toposort(),sam.work(sb);
    91     return 0;
    92 }
  • 相关阅读:
    Word操作技巧
    x264命令行参数解释
    [翻译]TCP穿透NAT技术
    VC6随身笔记
    如何开启 Windows 2000 Server 上的远程桌面功能
    MFC基础知识整理
    用Windows Media编码器建网络电视直播站
    在线播放器代码大全
    关于嵌入式系统方向
    老外搜集的Windows快捷键大全(2007110更新)
  • 原文地址:https://www.cnblogs.com/weeping/p/7526023.html
Copyright © 2011-2022 走看看