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

    题解:

    跟找最长公共子串几乎差不多的方法在后缀自动机上跑

    找到一个匹配点,ans+=sum[x]

    其中sum[x]=sum[fa]+(len[x]-len[fa[x]])*size[x]

    另外一个比较通用的方法

    是建立广义后缀自动机

    那么每个点的贡献是(len[x]-len[fa[x]])*size1[x]*size2[x]

    后缀数组也可解

    将两个串相连

    枚举最小值单调栈维护就可以了

    代码(广义后缀自动机):

    *对建立过程的特判以后再研究一下

    #include <bits/stdc++.h>
    #define ll long long
    #define rint register int
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    using namespace std;
    const int N=3e6;
    char s[N];
    int size[N][2],len[N],ch[N][26];
    int lst=1,node=1,t[N],a[N],fa[N],pl;
    void extend(int c)
    {
      int f=lst;
      if (ch[f][c]&&len[ch[f][c]]==len[f]+1)
      { 
        lst=ch[f][c];
        return;
      }
      int p=++node; lst=p;
      len[p]=len[f]+1; //size[p][pl]=1;
      while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f];
      if (!f) { fa[p]=1; return;};
      int x=ch[f][c],y=++node;
      if (len[f]+1==len[x]) {fa[p]=x; node--;return;};
      len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y;
      memcpy(ch[y],ch[x],sizeof(ch[x]));
      while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f];
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      ios::sync_with_stdio(false);
      cin>>s;
      int l=strlen(s);
      rep(i,1,l) extend(s[i-1]-'a'),size[lst][0]++;
      lst=1; pl=1;
      cin>>s;
      l=strlen(s);
      rep(i,1,l) extend(s[i-1]-'a'),size[lst][1]++; 
      rep(i,1,node) t[len[i]]++;
      rep(i,1,node) t[i]+=t[i-1];
      rep(i,1,node) a[t[len[i]]--]=i;
      dep(j,node,1)
      {
        int i=a[j];
        size[fa[i]][1]+=size[i][1];
        size[fa[i]][0]+=size[i][0]; 
      }
     // cout<<node<<endl; 
      ll ans=0;
      rep(i,1,node)
      if (fa[i])
        ans+=1ll*(len[i]-len[fa[i]])*size[i][1]*size[i][0];
      cout<<ans<<endl;
      return 0;
    }
  • 相关阅读:
    HashMap的实现原理
    LinkedHashMap的实现讲解
    ConcurrentHashMap原理分析
    javax.mail Java Extension(扩展)
    Singleton 单例模式
    Java序列化与反序列化(实践)
    Java IO操作
    Java NIO与IO的区别和比较
    java模拟异步消息的发送与回调
    java如何实现多个线程并发运行
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9353891.html
Copyright © 2011-2022 走看看