zoukankan      html  css  js  c++  java
  • 【BZOJ4566】【HAOI2016】找相同字符

    后缀自动姬好,好写好调好ac

    原题:

    给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两
    个子串中有一个位置不同。
    1 <=n1, n2<= 20000
     
    之前写了个后缀数组+并查集的,因为我只会后缀数组……
    后看看dalao们纷纷使用后缀自动姬秒题,决定提高一下自己姿势水平,学一发后缀自动姬
    然后根本无法理解啊quq,现在板子差不多理解了,但是自动姬上做DP的延伸还是不能理解quq
    多做题应该就能理解了吧……
    这题dp具体思路是啥我也没搞懂,直接上结论
    每个点的贡献:|right(x)|*(max[x]-max[fa[x]])
    具体贡献到答案上,就搞一个b在当前节点上匹配的公共长度l,然后对答案的贡献就是|right(x)|*(l-max[fa[x]])
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long
     8 int rd(){int z=0,mk=1;  char ch=getchar();
     9     while(ch<'0'||ch>'9'){if(ch=='-')mk=-1;  ch=getchar();}
    10     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    11     return z*mk;
    12 }
    13 char a[210000],b[210000];  int n,m;
    14 int nxt[810000][26],fa[810000],mx[810000],sz[810000];
    15 int lst=1,tt=1;
    16 int cnt[810000],cntrk[810000];
    17 ll f[810000];
    18 void ist(int x){
    19     int p=lst,np=lst=++tt;
    20     mx[np]=mx[p]+1;  sz[np]=1;
    21     while(!nxt[p][x] && p)  nxt[p][x]=np,p=fa[p];
    22     if(!p)  fa[np]=1;
    23     else{
    24         int q=nxt[p][x];
    25         if(mx[p]+1==mx[q])  fa[np]=q;
    26         else{
    27             int nq=++tt;  mx[nq]=mx[p]+1;
    28             memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
    29             fa[nq]=fa[q],fa[q]=fa[np]=nq;
    30             while(nxt[p][x]==q)  nxt[p][x]=nq,p=fa[p];
    31         }
    32     }
    33 }
    34 void gtcntrk(){
    35     for(int i=1;i<=tt;++i)  ++cnt[mx[i]];
    36     for(int i=1;i<=n;++i)  cnt[i]+=cnt[i-1];
    37     for(int i=tt;i;--i)  cntrk[cnt[mx[i]]--]=i;
    38 }
    39 void gtf(){
    40     for(int i=tt;i;--i)  sz[fa[cntrk[i]]]+=sz[cntrk[i]];
    41     for(int i=1;i<=tt;++i)
    42         f[cntrk[i]]=f[fa[cntrk[i]]]+(ll)sz[cntrk[i]]*(mx[cntrk[i]]-mx[fa[cntrk[i]]]);
    43 }
    44 int main(){//freopen("ddd.in","r",stdin);
    45     scanf("%s%s",a+1,b+1);  n=strlen(a+1),m=strlen(b+1);
    46     for(int i=1;i<=n;++i)  ist(a[i]-'a');
    47     gtcntrk(),gtf();
    48     ll bwl=0;  int l=0,tmp=1,x;
    49     for(int i=1;i<=m;++i){
    50         x=b[i]-'a';
    51         if(nxt[tmp][x])  tmp=nxt[tmp][x],++l;
    52         else{
    53             while(!nxt[tmp][x] && tmp)  tmp=fa[tmp];
    54             if(!tmp)  tmp=1,l=0;
    55             else  l=mx[tmp]+1,tmp=nxt[tmp][x];
    56         }
    57         if(tmp!=1)  bwl+=f[fa[tmp]]+(ll)sz[tmp]*(l-mx[fa[tmp]]);
    58     }
    59     cout<<bwl<<endl;
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/JSL2018/p/6544869.html
Copyright © 2011-2022 走看看