zoukankan      html  css  js  c++  java
  • 2017.3.4[hihocoder#1403]后缀数组一·重复旋律

    好久没发博了。

    后缀数组板子题。具体实现就不解释了,hihocoder很良心。

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

     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 20010
    10 #define RG register
    11 #define inf 0x3f3f3f3f
    12 #define Inf 99999999999999999LL
    13 using namespace std;
    14 typedef long long LL;
    15 int h,k,n,t,ans,a[N],b[N],q[N],sa[N],ssa[N],cnta[N],cntb[N],heit[N],Rank[N],music[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 (int i=1;i<=n;++i)   ++cnta[music[i]];
    28     for (int i=1;i<=100;++i) cnta[i]+=cnta[i-1];
    29     for (int i=n;i;--i)      sa[cnta[music[i]]--]=i;
    30     Rank[sa[1]]=1;
    31     for (int i=2;i<=n;++i){
    32         Rank[sa[i]]=Rank[sa[i-1]];
    33         if(music[sa[i]]!=music[sa[i-1]])
    34             ++Rank[sa[i]];
    35     }
    36     for (int now=1;Rank[sa[n]]<n;now<<=1){
    37     memset(cnta,0,sizeof(cnta));
    38     memset(cntb,0,sizeof(cntb));
    39         for (int i=1;i<=n;++i){
    40             ++cnta[a[i]=Rank[i]];                 //rank即为上一次排序好的第一关键字
    41             ++cntb[b[i]=(i+now<=n)?Rank[i+now]:0];//rank[i+now]即为第二关键字
    42         }
    43         for (int i=1;i<=n;++i) cntb[i]+=cntb[i-1];
    44         for (int i=n;i;--i)    ssa[cntb[b[i]]--]=i;//ssa即为按第二关键字排的“假”sa
    45         for (int i=1;i<=n;++i) cnta[i]+=cnta[i-1];
    46         for (int i=n;i;--i)    sa[cnta[a[ssa[i]]]--]=ssa[i];//相当于把i替换为ssa[i],从而达到双关键字排序的目的
    47         Rank[sa[1]]=1;
    48         for (int i=2;i<=n;++i){
    49             Rank[sa[i]]=Rank[sa[i-1]];
    50             if (a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]]) ++Rank[sa[i]];
    51         }
    52     }
    53     for (int i=1,j=0;i<=n;++i){
    54         if(j) --j;
    55         while (music[i+j]==music[sa[Rank[i]-1]+j]) ++j;
    56         heit[Rank[i]]=j;
    57     }
    58 }   
    59 inline void work(){
    60     n=gi();k=gi();
    61     if(k==1){
    62     printf("%d
    ",n);
    63     return;
    64     }
    65     for (RG int i=1;i<=n;++i)
    66     music[i]=gi();
    67     getsa();
    68     //for (RG int i=1;i<=n;++i) cout<<heit[i]<<' ';
    69     //cout<<endl;
    70     for (RG int i=1;i<=n;++i){
    71     while(h<t&&heit[i]<heit[q[t]]) --t;
    72     q[++t]=i;
    73     //cout<<q[h+1]<<' '<<q[t]<<endl;
    74     while(q[h+1]<=q[t]-k+1) ++h;
    75     if(h<t) ans=Max(ans,heit[q[h+1]]);
    76     //cout<<ans<<endl;
    77     }
    78     printf("%d
    ",ans);
    79 }
    80 int main(){
    81     work();
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    NSDate
    Info.plist字段列表详解
    面向对象编程思想以及强、弱引用总结
    分类(类别/Category)与 类扩展(Extension)
    UIAlertView
    SQLite3的运用
    快速创建单例
    C++ 常用设计模式
    I2S 总线学习:2-I2S驱动WM8978
    设计模式的七大原则
  • 原文地址:https://www.cnblogs.com/Super-Nick/p/6502486.html
Copyright © 2011-2022 走看看