标签:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 21134 | Accepted: 7234 |
Description
Input
Output
Sample Input
30 25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18 82 78 74 70 66 67 64 60 65 80 0
Sample Output
5
Hint
Source
/** 题意:百度的题意,根据罗的论文知道了题意,但是没有懂,百度了一下, 给出一段只有音高(整数表示),没有节奏的乐谱,问其中最长的曲调相同的没有重叠的两段的长度是多少。 做法:将给的高音进行后以为 - 前一位 + 90 ,然后进行da(),并且用二分进行查 **/ #include <iostream> #include <string.h> #include <stdio.h> #include <cmath> #include <algorithm> #include <queue> #define maxn 20000 +100 using namespace std; int t1[maxn],t2[maxn],c[maxn]; bool cmp(int *r,int a,int b,int l) { return r[a] == r[b] && r[a+l] == r[b+l]; } int sa[maxn]; int Rank[maxn]; int heigth[maxn]; void da(int str[],int n,int m) { n++; int i,j,p, *x = t1,*y = t2; for(i=0; i<m; i++) c[i] = 0; for(i=0; i<n; i++) c[x[i] = str[i]]++; for(i=1; i<m; i++) c[i] += c[i-1]; for(i=n-1; i>=0; i--) sa[--c[x[i]]] = i; for(j=1; j<=n; j<<=1) { p = 0; for(i=n-j; i<n; i++) y[p++] = i; for(i=0; i<n; i++) if(sa[i] >= j) y[p++] = sa[i] - j; for(i=0; i<m; i++) c[i] = 0; for(i=0; i<n; i++) c[x[y[i]]]++; for(i=1; i<m; i++) c[i] += c[i-1]; for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for(i=1; i<n; i++) x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++; if(p >=n) break; m = p; } int k =0 ; n--; for(i=0; i<=n; i++) Rank[sa[i]] = i; for(i =0 ; i<n; heigth[Rank[i++]] = k) { for(k?k--:0,j = sa[Rank[i]-1]; str[i+k] == str[j+k]; k++); } } int n; int mm[maxn]; bool check(int mid,int len) { for(int i=2; i<=len; i++) { if(heigth[i] < mid) continue; ///因为heigth数组中存储的是suffix(sa[i])和suffix(sa[i-1])的公共前缀的个数 /// 所以只有但heigth[i] >= mid 才能进行查询 否则没有 for(int j= i-1; j>=2; j--) { if(abs(sa[i] - sa[j]) >= mid) { return true; } if(heigth[j] < mid) break; } } return false; } int main() { //#ifndef ONLINE_JUDGE // freopen("in.txt","r",stdin); //#endif while(~scanf("%d",&n)) { if(n == 0) break; memset(heigth,0,sizeof(heigth)); memset(mm,0,sizeof(mm)); memset(Rank,0,sizeof(Rank)); memset(sa,0,sizeof(sa)); n--; for(int i=0; i<=n; i++) { scanf("%d",&mm[i]); } if(n < 10) { printf("0\n"); continue; } for(int i=0; i<n; i++) { mm[i] = mm[i+1] - mm[i] +90; } mm[n] = 0; da(mm,n,200); int left = 3,mid,right = n; int ans = 0; while(left <= right) { mid = (left + right) >> 1; if(check(mid,n)) { left = mid + 1; ans = mid ; } else right = mid - 1; } if(ans < 4) printf("%d\n",ans); else printf("%d\n",ans+1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/chenyang920/p/4571444.html