zoukankan      html  css  js  c++  java
  • hihocoder #1419 : 后缀数组四·重复旋律4

    http://hihocoder.com/problemset/problem/1419

    这个题可以用类似https://www.cnblogs.com/hehe54321/p/8808226.html的方法A掉,分析比题解要简单...(应该吧?)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 typedef long long LL;
     7 typedef unsigned long long ULL;
     8 char s[100010];
     9 LL n,anss;
    10 ULL powx[100100],hs[100100];
    11 const ULL X=131;
    12 ULL ghash(LL x,LL y)//[x,y]的哈希
    13 {
    14     return hs[x]-hs[y+1]*powx[y-x+1];
    15 }
    16 LL lcp(LL x,LL y)//后缀x和后缀y的lcp
    17 {
    18     if(x>n||y>n)    return 0;
    19     LL l=0,r=min(n-x+1,n-y+1)+1,mid;
    20     while(r-l>1)
    21     {
    22         mid=l+(r-l)/2;
    23         if(ghash(x,x+mid-1)==ghash(y,y+mid-1))    l=mid;
    24         else    r=mid;
    25     }
    26     return l;
    27 }
    28 LL lcs(LL x,LL y)//前缀x和前缀y的lcs
    29 {
    30     if(!x||!y)    return 0;
    31     LL l=0,r=min(x,y)+1,mid;
    32     while(r-l>1)
    33     {
    34         mid=l+(r-l)/2;
    35         if(ghash(x-mid+1,x)==ghash(y-mid+1,y))    l=mid;
    36         else    r=mid;
    37     }
    38     return l;
    39 }
    40 LL ans;
    41 int main()
    42 {
    43     LL i,j,b,l,r,k;
    44     scanf("%s",s+1);n=strlen(s+1);
    45     powx[0]=1;
    46     for(i=1;i<=100000;i++)    powx[i]=powx[i-1]*X;
    47     for(i=n;i>=1;i--)    hs[i]=hs[i+1]*X+s[i];
    48     for(i=1;i<=n;i++)
    49     {
    50         b=n/i;
    51         for(j=1,k=0;j<=b;j++)
    52         {
    53             for(;k<b&&ghash(i*(j-1)+1,i*j)==ghash(i*k+1,i*(k+1));k++);
    54             //例如对于dba,bca,bca,bde
    55             //当i=3,j=2时,k=3
    56             l=min(i-1,lcs(i*(j-1),i*k));r=min(i-1,lcp(i*(j-1)+1,i*k+1));
    57             //此时l=1,r=1
    58             ans=max(ans,k-j+1);
    59             //此时只可能分成两段的倍数,且长度为k-j+1
    60             //又例如:当i=3,j=3,k=3时
    61             //l=2,r=1
    62             //k-j+1=1,因此没有需要统计的
    63             if(l+r>=i)    ans=max(ans,k-j+2);
    64             //但事实上有cabcab没有统计
    65             //可以证明,像这种情况漏统计的串的循环次数最多比k-j+1大1
    66             //漏统计的数量是从第i*(j-1)-l+1位开始的到第i*(j-1)+r-i+1位开始的
    67             //共出现r+l-i+1次,每一次均循环k-j+2次
    68             //显然只有当r+l-i+1大于0时才会有此情况
    69             //又例如:例如ac,cc,c,当i=2,j=2,k=2,l=1,r=1时
    70             //此时还有cccc被漏统计
    71             //从第2位开始,到第2位结束,重复2次
    72         }
    73     }
    74     printf("%lld",ans);
    75     return 0;
    76 }
  • 相关阅读:
    easyui里弹窗的两种表现形式
    如何获得 request, "request.getSession(true).setAttribute("a",a);"与“request.setAttribute("a",a);”区别
    JSTL和EL的区别
    windows下安装多个tomcat服务
    谷歌浏览器控制台使用
    递归和迭代有什么区别?
    left join ,right join ,inner join ,cross join 区别
    sql良好习惯
    添加了一个字段,查询速度突然变慢
    热点账户问题-转
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8808281.html
Copyright © 2011-2022 走看看