• 2017.3.4[hihocoder#1407]后缀数组二·重复旋律2


    重复旋律大礼包

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

     1 #include<cmath>
     2 #include<queue>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cstring>
     7 #include<iostream>
     8 #include<algorithm>
     9 #define N 100010
    10 #define RG register
    11 #define inf 0x3f3f3f3f
    12 #define Inf 99999999999999999LL
    13 using namespace std;
    14 typedef long long LL;
    15 int l=1,n,r,ans,a[N],b[N],sa[N],num[N],ssa[N],cnta[N],cntb[N],heit[N],order[N];
    16 inline int Abs(RG const int &a){return a>0?a:-a;}
    17 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;}
    18 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;}
    19 inline int gi(){
    20     RG int x=0;RG bool flag=0;RG char c=getchar();
    21     while((c<'0'||c>'9')&&c!='-') c=getchar();
    22     if(c=='-') c=getchar(),flag=1;
    23     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    24     return flag?-x:x;
    25 }
    26 inline void getsa(){
    27     for (RG int i=1;i<=n;++i)    ++cnta[num[i]];
    28     for (RG int i=1;i<=1000;++i) cnta[i]+=cnta[i-1];
    29     for (RG int i=n;i;--i)       sa[cnta[num[i]]--]=i;
    30     order[sa[1]]=1;
    31     //cout<<"sdmo"<<endl;
    32     if(n>1){
    33     for (RG int i=2;i<=n;++i){
    34         order[sa[i]]=order[sa[i-1]];
    35         if(num[sa[i]]!=num[sa[i-1]]) ++order[sa[i]];
    36     }
    37     //cout<<"cdsamoc"<<endl;
    38         for (RG int now=1;order[sa[n]]<n;now<<=1){
    39         memset(cnta,0,sizeof(cnta));
    40         memset(cntb,0,sizeof(cntb));
    41         for (RG int i=1;i<=n;++i){
    42             ++cnta[a[i]=order[i]];
    43             ++cntb[b[i]=(i+now<=n)?order[i+now]:0];
    44         }
    45         for (RG int i=1;i<=n;++i) cntb[i]+=cntb[i-1];
    46         for (RG int i=n;i;--i)    ssa[cntb[b[i]]--]=i;
    47         for (RG int i=1;i<=n;++i) cnta[i]+=cnta[i-1];
    48         for (RG int i=n;i;--i)    sa[cnta[a[ssa[i]]]--]=ssa[i];
    49         order[sa[1]]=1;
    50         for (RG int i=2;i<=n;++i){
    51         order[sa[i]]=order[sa[i-1]];
    52         if(a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]]) ++order[sa[i]];
    53         }
    54     }
    55     //cout<<"dsji"<<endl;
    56     }
    57     for (RG int i=1,j=0;i<=n;++i){
    58     if(j) --j;
    59     while(num[i+j]==num[sa[order[i]-1]+j]) ++j;
    60     heit[order[i]]=j;
    61     }
    62 }
    63 inline bool check(RG int mid){
    64     RG int maxn,minn=inf;
    65     for (RG int i=1;i<=n;++i)
    66     if(heit[i]<mid)
    67         maxn=minn=sa[i];
    68     else{
    69         maxn=Max(maxn,sa[i]);
    70         minn=Min(minn,sa[i]);
    71         if(maxn-minn>=mid) return 1;
    72     }
    73     return 0;
    74 }
    75 inline void work(){
    76     n=gi();r=n;
    77     for (RG int i=1;i<=n;++i) num[i]=gi();
    78     //cout<<"cesj"<<endl;
    79     getsa();
    80     //cout<<"feanfila"<<endl;
    81     while(l<=r){
    82     RG int mid=(l+r)>>1;
    83     if(check(mid)) ans=mid,l=mid+1;
    84     else           r=mid-1;
    85     }
    86     printf("%d
    ",ans);
    87 }
    88 int main(){
    89     work();
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    Java 面向对象(二)封装
    Java 面向对象(一)面向对象思想
    Java 字符串(二)字符串常用操作
    Java 字符串(一)字符串初始化
    JavaScript 流程控制(二)循环结构
    【剑指Offer-知识迁移能力】面试题58:翻转单词顺序
    【剑指Offer-知识迁移能力】面试题57.2:和为s的连续整数序列
    【剑指Offer-知识迁移能力】面试题57:合为s的两个数字
    【剑指Offer-知识迁移能力】面试题56:数组中只出现一次的两个数字
    【剑指Offer-知识迁移能力】面试题55.2:平衡二叉树
  • 原文地址:https://www.cnblogs.com/Super-Nick/p/6502676.html
Copyright © 2020-2023  润新知