zoukankan      html  css  js  c++  java
  • hdu 3518 Boring counting

    枚举子串的长度,然后判断是不是最远位置和最近的相隔满足大于等于子串的长度就好,,(然而本蒟蒻还是不会)

     1 #include<bits/stdc++.h>
     2 #define N 100005<<2
     3 #define LL long long
     4 #define inf 0x3f3f3f3f
     5 using namespace std;
     6 inline int ra()
     7 {
     8     int x=0,f=1; char ch=getchar();
     9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    11     return x*f;
    12 }
    13 int n,k,p,q,ans;
    14 int a[1005],v[1005];
    15 int sa[2][1005],rk[2][1005],h[1005];
    16 char ch[1005];
    17 void cal_sa(int sa[N], int rk[N], int Sa[N], int Rk[N])
    18 {
    19     for (int i=1; i<=n; i++) v[rk[sa[i]]]=i;
    20     for (int i=n; i>=1; i--)
    21         if (sa[i]>k) Sa[v[rk[sa[i]-k]]--]=sa[i]-k;
    22     for (int i=n-k+1; i<=n; i++)
    23         Sa[v[rk[i]]--]=i;
    24     for (int i=1; i<=n; i++) Rk[Sa[i]]=Rk[Sa[i-1]]+(rk[Sa[i]]!=rk[Sa[i-1]] || rk[Sa[i]+k]!=rk[Sa[i-1]+k]);
    25 }
    26 void work()
    27 {
    28     p=0,q=1;
    29     for (int i=1; i<=n; i++) v[a[i]]++;
    30     for (int i=1; i<=30; i++) v[i]+=v[i-1];
    31     for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i;
    32     for (int i=1; i<=n; i++) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
    33     for (k=1; k<n; k<<=1,q^=1,p^=1) cal_sa(sa[p],rk[p],sa[q],rk[q]);
    34 }
    35 void get_height()
    36 {
    37     k=0;
    38     for (int i=1; i<=n; i++)
    39     {
    40         if (rk[p][i]==1) h[1]=0;
    41         else{
    42             int j=sa[p][rk[p][i]-1];
    43             while (a[i+k]==a[j+k]) k++;
    44             h[rk[p][i]]=k;
    45             if (k>0) k--;
    46         }
    47     }
    48 }
    49 bool solve(int x)
    50 {
    51     bool flag=0;
    52     int mx=sa[p][1],mn=sa[p][1];
    53     for (int i=2; i<=n; i++)
    54         if (h[i]<x)
    55         {
    56             if (mx-mn>=x) ans++,flag=1;
    57             mx=mn=sa[p][i];
    58         }
    59         else
    60         {
    61             mx=max(mx,sa[p][i]);
    62             mn=min(mn,sa[p][i]);
    63         }
    64     if (mx-mn>=x) ans++,flag=1;
    65     return flag;
    66 }
    67 int main()
    68 {
    69     while (scanf("%s",ch+1))
    70     {
    71         if (ch[1]=='#') break;
    72         memset(a,0,sizeof(a));
    73         memset(v,0,sizeof(v));
    74         memset(rk,0,sizeof(rk));
    75         memset(sa,0,sizeof(sa));
    76         n=strlen(ch+1);
    77         for (int i=1; i<=n; i++) a[i]=ch[i]-'a'+1;
    78         work(); get_height();
    79         ans=0; 
    80         for (int i=1; i<=(n+1)/2; i++)
    81             if (!solve(i)) break;
    82         cout<<ans<<endl;
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    PHP设计模式之----简单工厂模式
    PHP设计模式之----单例模式
    php排序算法
    PHP代码实现二分法查找
    Centos 7 下安装PHP7.2(与Apache搭配的安装方式)
    PHPSTORM Live-Templates变量速查表
    Centos 7 设置ip地址
    Centos 7下编译安装Apache
    Centos 7下编译安装Mysql
    apache配置Directory目录权限的一些配置
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6477184.html
Copyright © 2011-2022 走看看