zoukankan      html  css  js  c++  java
  • BZOJ3676: [Apio2014]回文串

    3676: [Apio2014]回文串

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 211  Solved: 51
    [Submit][Status]

    Description

    考虑一个只包含小写拉丁字母的字符串s。我们定义s的一个子串t的“出
    现值”为t在s中的出现次数乘以t的长度。请你求出s的所有回文子串中的最
    大出现值。

    Input

    输入只有一行,为一个只包含小写字母(a -z)的非空字符串s。

    Output


    输出一个整数,为逝查回文子串的最大出现值。

    【数据规模与评分】

    数据满足1≤字符串长度≤300000。

    题解:

    总算A了这题,感觉好舒畅。。。

    首先我们要知道一个结论:

    只有使mx变大的回文串,才是与之前所有回文子串不同的新串,否则一定可以由之前的回文串关于id对称得到
    所以本质不同的回文子串数量是O(N)级别的

    因为我们不能把所有找到的回文串都去跑一遍。。。

    所以我们manacher的时候顺便找出所有的本质不同的回文字串,并且把每个放到后缀数组里面跑一遍看看出现了多少次。

    然后就可以更新答案了。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 650000+5
     26 
     27 #define maxm 20000000+5
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define mod 1000000007
     44 
     45 using namespace std;
     46 
     47 inline int read()
     48 
     49 {
     50 
     51     int x=0,f=1;char ch=getchar();
     52 
     53     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     54 
     55     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     56 
     57     return x*f;
     58 
     59 }
     60 int n,m;
     61 int t1[maxn],t2[maxn],c[maxn],a[maxn],sa[maxn],rk[maxn],h[maxn],st[maxn][20];
     62 int b[maxn],p[maxn];
     63 char s[maxn];
     64 void getsa(int m)
     65 {
     66     int *x=t1,*y=t2;
     67     for0(i,m)c[i]=0;
     68     for0(i,n)c[x[i]=a[i]]++;
     69     for1(i,m)c[i]+=c[i-1];
     70     for3(i,n,0)sa[--c[x[i]]]=i;
     71     for(int k=1;k<=n+1;k<<=1)
     72     {
     73         int p=0;
     74         for2(i,n-k+1,n)y[p++]=i;
     75         for0(i,n)if(sa[i]>=k)y[p++]=sa[i]-k;
     76         for0(i,m)c[i]=0;
     77         for0(i,n)c[x[y[i]]]++;
     78         for1(i,m)c[i]+=c[i-1];
     79         for3(i,n,0)sa[--c[x[y[i]]]]=y[i];
     80         swap(x,y);p=0;x[sa[0]]=0;
     81         for1(i,n)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p:++p;
     82         if(p>=n)break;
     83         m=p;
     84     }
     85     for1(i,n)rk[sa[i]]=i;
     86     for(int i=0,k=0,j;i<n;h[rk[i++]]=k)
     87         for(k?k--:0,j=sa[rk[i]-1];a[i+k]==a[j+k];k++);
     88 }
     89 void getst()
     90 {
     91     int k=log2(n);
     92     for1(i,n)st[i][0]=h[i];
     93     for1(j,k)for1(i,n-(1<<j)+1)st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
     94 }
     95 inline int rmq(int x,int y)
     96 {
     97     int k=log2(y-x+1);
     98     return min(st[x][k],st[y-(1<<k)+1][k]);
     99 }
    100 inline ll query(int x,int y)
    101 {
    102     int l,r,mid,ql,qr;
    103     if(h[x+1]<y)qr=x;
    104     else
    105     {
    106         l=x+1;r=n;
    107         while(l<=r)
    108         {
    109             mid=(l+r)>>1;
    110             if(rmq(x+1,mid)>=y)l=mid+1;else r=mid-1;
    111         }
    112         qr=r;
    113     }
    114     if(h[x]<y)ql=x;
    115     else
    116     {
    117         l=1;r=x-1;
    118         while(l<=r)
    119         {
    120             mid=(l+r)>>1;
    121             //cout<<l<<' '<<mid<<' '<<r<<endl;
    122             if(rmq(mid+1,x)>=y)r=mid-1;else l=mid+1;
    123         }
    124         ql=l;
    125     }
    126     //cout<<x<<' '<<y<<' '<<ql<<' '<<qr<<endl;
    127     /*for2(i,sa[x],sa[x]+y-1)cout<<s[i];
    128     cout<<' '<<ql<<' '<<qr<<endl;*/
    129     return (ll)(qr-ql+1)*(ll)y;
    130 }
    131 
    132 int main()
    133 
    134 {
    135 
    136     freopen("input.txt","r",stdin);
    137 
    138     freopen("output.txt","w",stdout);
    139 
    140     scanf("%s",s);n=strlen(s);
    141     for0(i,n-1)a[i]=s[i]-'a'+1;a[n]=0;
    142     getsa(26);getst();
    143     for0(i,n-1)b[(i+1)<<1]=a[i];
    144     m=(n<<1)+1;
    145     int id=0,mx=0;ll ans=0;
    146     for1(i,m)
    147     {
    148         if(mx>i)p[i]=min(p[2*id-i],mx-i);
    149         while(i-p[i]-1>0&&i+p[i]+1<=m&&b[i-p[i]-1]==b[i+p[i]+1])p[i]++;
    150         if(i+p[i]>mx)
    151         {
    152             mx=i+p[i];
    153             id=i;
    154             ans=max(ans,query(rk[(i-p[i]-1)>>1],p[i]));
    155             //cout<<i<<' '<<p[i]<<' '<<(i-p[i]-1>>1)<<' '<<(rk[(i-p[i]-1)>>1])<<endl;
    156         }
    157     }
    158     //for1(i,m)cout<<i<<' '<<b[i]<<' '<<p[i]<<endl;
    159     printf("%lld
    ",ans);
    160 
    161     return 0;
    162 
    163 }  
    View Code

    据说也可以hash做?不明觉厉

     

     

  • 相关阅读:
    js如何实现上拉加载更多...
    基于epoll的TP传输层实现
    ActiveMQ简介与安装
    序列化和反序列化实现
    NoSQL之Redis数据库初探
    分布式缓存之memcached--命令测试
    Java正则表达式测试用例
    Java之正则表达式
    Java反射机制练习(增强可扩展性)
    Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4156028.html
Copyright © 2011-2022 走看看