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

    2320: 最多重复子串

    Time Limit: 40 Sec  Memory Limit: 128 MB
    Submit: 246  Solved: 66
    [Submit][Status][Discuss]

    Description

    一个字符串P的重复数定义为最大的整数R,使得P可以分为R段连续且相同的子串。比方说,“ababab”的重复数为3,“ababa”的重复数为1。

    Your Task

    对于给定的串S,找出S的一个子串K使得K的重复数最大。

     

    Input

    第一行T表示数据组数

    对于每组数据,一行中一个仅包含小写字母的字符串S

     

    Output

    对于每组数据,在一行中输出K,如果有多个解,输出字典序最小的那一个

     

    Sample Input

    2
    ccabababc
    daabbccaa

    Sample Output


    ababab
    aa

    HINT

    100%:T≤10,S的长度不超过100000

    题解

    ……我就来贴个代码吧……orz下claris……

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 typedef unsigned long long ll;
     5 const int N=100010,base=127;
     6 int ans,k,st,ed,n,m,time,i,l;char s[N];ll f[N],pow[N];
     7 using namespace std;
     8 ll hash(int l,int r){return f[r]-f[l-1]*pow[r-l+1];}
     9 int lcs(int x,int y)
    10 {
    11     int l=0,r=min(x,y);
    12     while(l<r){
    13         int mid=(l+r)/2;
    14         if(hash(x-mid,x)==hash(y-mid,y))l=mid+1;else r=mid;
    15     }
    16     return l;
    17 }
    18 int lcp(int x,int y)
    19 {
    20     int l=0,r=min(n-x+1,n-y+1);
    21     while(l<r){
    22         int mid=(l+r)/2;
    23         int a=hash(x,x+mid);
    24         int b=hash(y,y+mid);
    25         if(hash(x,x+mid)==hash(y,y+mid))l=mid+1;else r=mid;
    26     }
    27     return l;
    28 }
    29 void up(int x,int y)
    30 {
    31     if(k>ans){ans=k;st=x;ed=y;return;}
    32     int l0=ed-st+1,l1=y-x+1,t=lcp(x,st);
    33     if(t==min(l0,l1)){
    34         if(t==l0)return;
    35         st=x;ed=y;return;
    36     }
    37     if(s[st+t]>s[x+t]){st=x;ed=y;}
    38 }
    39 int main()
    40 {
    41     scanf("%d",&time);
    42     for(i=1,pow[0]=1;i<=N;i++)pow[i]=pow[i-1]*base;
    43     while(time--)
    44     {
    45         scanf("%s",s+1);n=strlen(s+1);
    46         for(ans=st=ed=i=1;i<=n;i++)
    47             if(s[i]<s[st])st=ed=i;
    48         for(f[0]=0,i=1;i<=n;i++)f[i]=f[i-1]*base+s[i];
    49         for(int i=1;i<=n/2;i++)
    50             for(int j=1;j<=n;j+=i){
    51                 int x=j+i;if(x>n)break;
    52                 if(s[j]!=s[x])continue;
    53                 int a=lcp(j,x),b=lcs(j,x);
    54                 k=(a+b-1)/i+1;
    55                 l=k*i;
    56                 if(k>=ans)for(int y=j-b+1;y<=i+j+a-l;y++)up(y,y+l-1);
    57             }
    58         for(int i=st;i<=ed;i++)putchar(s[i]);puts("");
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    (转)GNU风格ARM汇编语法指南(非常详细)5
    (转)ARM GNU常用汇编语言介绍
    RH850 FCL的使用
    RL78 FDL和FSL的使用
    RH850 中断相关
    关于const类型指针变量的使用
    Linux内核中双向链表的经典实现
    RL78 定义常量变量在指定的地址方法
    RL78 RAM GUARD Funtion
    AUTOSAR-Specification of Watchdog Manager 阅读
  • 原文地址:https://www.cnblogs.com/oldjang/p/6514007.html
Copyright © 2011-2022 走看看