zoukankan      html  css  js  c++  java
  • BZOJ2320 : 最多重复子串

    本题就是求重复数最多的字典序最小的$runs$,如果重复数为1,那么做法显然,然后只考虑重复数大于1的情况。

    从小到大枚举长度$len$,对于每个关键点$x=i imes len$,有且仅有一个长度为$len$的串经过它。

    算出$x$与$x+len$的最长公共前缀$A$和最长公共后缀$B$后,贡献为$lfloorfrac{A+B-1}{len} floor+1$。

    对于方案,可以暴力枚举所有可行起点,因为极大$runs$的总个数是$O(n)$的。

    时间复杂度$O(nlog^2n)$。

    #include<cstdio>
    #include<cstring>
    typedef unsigned long long ll;
    const int N=100010,D=13331;
    int T,n,m,i,j,k,x,y,A,B,L,ans,st,en;char a[N];ll pow[N],f[N];
    inline ll hash(int l,int r){return f[r]-f[l-1]*pow[r-l+1];}
    inline int min(int a,int b){return a<b?a:b;}
    inline int lcp(int x,int y){
      if(a[x]!=a[y])return 0;
      int l=2,r=min(n-x,n-y)+1,mid,t=1;
      while(l<=r){
        mid=(l+r)>>1;
        if(hash(x,x+mid-1)==hash(y,y+mid-1))l=(t=mid)+1;else r=mid-1;
      }
      return t;
    }
    inline int lcs(int x,int y){
      int l=2,r=x,mid,t=1;
      while(l<=r){
        mid=(l+r)>>1;
        if(hash(x-mid+1,x)==hash(y-mid+1,y))l=(t=mid)+1;else r=mid-1;
      }
      return t;
    }
    inline void up(int x,int y){
      if(k>ans){ans=k,st=x,en=y;return;}
      int l0=en-st+1,l1=y-x+1,t=min(lcp(x,st),min(l0,l1));
      if((t<l1?a[x+t]:0)<(t<l0?a[st+t]:0))st=x,en=y;
    }
    int main(){
      scanf("%d",&T);
      for(pow[0]=i=1;i<N;i++)pow[i]=pow[i-1]*D;
      while(T--){
        scanf("%s",a+1);n=strlen(a+1);
        for(ans=i=st=en=1;i<=n;i++)if(a[i]<a[st])st=en=i;
        for(i=1;i<=n;i++)f[i]=f[i-1]*D+a[i];
        for(i=1;i+i<=n;i++)for(j=i;j<=n;j+=i){
          x=j+i;
          if(x>n)break;
          if(a[j]!=a[x])continue;
          A=lcp(j,x),B=lcs(j,x),k=(A+B-1)/i+1;
          if(k>=ans&&k>1)for(L=k*i,y=j-B+1;y+L<=i+j+A;y++)up(y,y+L-1);
        }
        for(i=st;i<=en;i++)putchar(a[i]);puts("");
      }
      return 0;
    }
    

      

  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/clrs97/p/5277702.html
Copyright © 2011-2022 走看看