• [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp


    4566: [Haoi2016]找相同字符

    Time Limit: 20 Sec  Memory Limit: 256 MB
    Submit: 1212  Solved: 694
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

    输出一个整数表示答案

    Sample Input

    aabb
    bbaa

    Sample Output

    10

    HINT

     

    Source

    时隔许久后重新获得了后缀自动机技能。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<cstdio>
     7 #define maxn 200005
     8 #define ll long long
     9 using namespace std;
    10 inline int read() {
    11     int x=0,f=1;char ch=getchar();
    12     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    13     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    14     return x*f;
    15 }
    16 struct SUF {
    17     int sz[maxn*2],link[maxn*2],step[maxn*2],son[maxn*2][26],v[maxn*2],pos[maxn*2];
    18     int nxt[maxn*2],head[maxn*2],tto[maxn*2],tot;
    19     int cnt,last;
    20     SUF() {last=cnt=1;memset(head,-1,sizeof(head));}
    21     void extend(int c) {
    22         int p=last,np=last=++cnt;step[np]=step[p]+1;sz[np]=1;
    23         while(p&&!son[p][c]) son[p][c]=np,p=link[p];
    24         if(!p) link[np]=1;
    25         else {
    26             int q=son[p][c];
    27             if(step[q]==step[p]+1) link[np]=q;
    28             else {
    29                 int nq=++cnt;
    30                 memcpy(son[nq],son[q],sizeof(son[q]));
    31                 link[nq]=link[q];link[q]=link[np]=nq;
    32                 step[nq]=step[p]+1;
    33                 while(son[p][c]==q&&p) son[p][c]=nq,p=link[p];
    34             }
    35         }
    36     }
    37     void pre() {
    38         for(int i=1;i<=cnt;i++) v[step[i]]++;
    39         for(int i=1;i<=cnt;i++) v[i]+=v[i-1];
    40         for(int i=cnt;i>=1;i--) pos[v[step[i]]--]=i;
    41         for(int i=cnt;i>=1;i--) sz[link[pos[i]]]+=sz[pos[i]];
    42     }
    43     ll f[maxn*2];
    44     void dfs(int x) {
    45         f[x]+=1ll*sz[x]*(step[x]-step[link[x]]);
    46         for(int i=head[x];i>=0;i=nxt[i]) {
    47             int to=tto[i];f[to]+=f[x];dfs(to);
    48         }
    49     }
    50     void add(int u,int v) {
    51         nxt[tot]=head[u];tto[tot]=v;head[u]=tot++;
    52     }
    53 }t;
    54 char ch[maxn];
    55 int main() {
    56     scanf("%s",ch+1);int len=strlen(ch+1);
    57     for(int i=1;i<=len;i++) t.extend(ch[i]-'a');
    58     t.pre();
    59     scanf("%s",ch+1);len=strlen(ch+1);
    60     for(int i=1;i<=t.cnt;i++) if(t.link[i]) t.add(t.link[i],i);t.dfs(1);
    61     int now=1,l=0;ll ans=0;
    62     for(int i=1;i<=len;i++) {
    63         int to=ch[i]-'a';
    64         while(now&&!t.son[now][to]) now=t.link[now];
    65         if(!now) now=1,l=0;
    66         else l=min(l,t.step[now])+1,now=t.son[now][to];
    67         ans+=t.f[t.link[now]];ans+=1ll*(l-t.step[t.link[now]])*t.sz[now];
    68     }
    69     printf("%lld
    ",ans);
    70 }
    View Code
  • 相关阅读:
    Redis实现分布式锁
    Redis数据结构
    Mysql与redis缓存一致性
    mysql分库分表
    mysql主从同步
    mysql配置优化
    Netty 参数优化
    JAVA多线程之park & unpack
    网络时钟服务器(网络校时服务器)无法同步的排查方法
    GPS北斗共视授时中的多径效应分析
  • 原文地址:https://www.cnblogs.com/wls001/p/10028215.html
Copyright © 2020-2023  润新知