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",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\n",ans);
79 }
80 int main(){
81     work();
82     return 0;
83 }

时间: 2024-10-12 12:56:53

2017.3.4[hihocoder#1403]后缀数组一·重复旋律的相关文章

HihoCoder - 1403 后缀数组一&#183;重复旋律

描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列. 小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律.旋律是一段连续的数列,相似的旋律在原数列可重叠.比如在1 2 3 2 3 2 1 中 2 3 2 出现了两次. 小Hi想知道一段旋律中出现次数至少为K次的旋律最长是多少? 输入 第一行两个整数 N和K.1≤N≤20000 1≤K≤N 接下来有 N 个整数,表示每个音的数字.1≤数字≤100 输出 一行一个整数,表示答案. Sample I

hihocoder #1407 : 后缀数组二&#183;重复旋律2

#1407 : 后缀数组二·重复旋律2 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次

hihocoder #1415 : 后缀数组三&#183;重复旋律3

#1415 : 后缀数组三·重复旋律3 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分. 旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过.小Hi想

后缀数组四&#183;重复旋律4

后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段旋律称为(k,l)-重复的,如果它满足由一个长度为l的字符串重复了k次组成. 如旋律abaabaabaaba是(4,3)重复的,因为它由aba重复4次组成. 小Hi想知道一部作品中k最大的(k,l)-重复旋律. 解题方法提示 输入 一

hiho一下123周 后缀数组四&#183;重复旋律

后缀数组四·重复旋律4 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有重复的部分. 我们把一段旋律称为(k,l)-重复的,如果它满足由一个长度为l的字符串重复了k次组成. 如旋律abaabaabaaba是(4,3)重复的,因为它由aba重复4次组成. 小Hi想知道一部作品中k最大的(k,l)-重复旋律. 解题方法提示 输入 一

hiho一下122周 后缀数组三&#183;重复旋律

后缀数组三·重复旋律3 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分. 旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过.小Hi想知道两部作品的共同旋律最长是多少? 解题方法提示 输入 共两行.一

后缀数组二&#183;重复旋律2

后缀数组二·重复旋律2 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次的旋律最长是多少? 解题方法提示 输入 第一行一个整数 N.1≤

hiho一下121周 后缀数组二&#183;重复旋律2

后缀数组二·重复旋律2 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列.小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律. 旋律可以表示为一段连续的数列,相似的旋律在原数列不可重叠,比如在1 2 3 2 3 2 1 中 2 3 2 出现了一次,2 3 出现了两次,小Hi想知道一段旋律中出现次数至少为两次的旋律最长是多少? 解题方法提示 输入 第一行一个整数 N.1≤N

hiho一下120周 后缀数组一&#183;重复旋律

后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列. 小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律.旋律是一段连续的数列,相似的旋律在原数列可重叠.比如在1 2 3 2 3 2 1 中 2 3 2 出现了两次. 小Hi想知道一段旋律中出现次数至少为K次的旋律最长是多少? 解题方法提示 输入 第一行两个整数 N和K.1≤N≤20000 1≤K≤N