标签:
做出公差后找出最长不重叠子序列的长度。
后缀数组的模板, 二分长度k然后将height数组分组, 判断每一组内sa的最大值-sa的最小值是否大于等于k, 如果大于等于k则满足。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 using namespace std; 14 #define pb(x) push_back(x) 15 #define ll long long 16 #define mk(x, y) make_pair(x, y) 17 #define lson l, m, rt<<1 18 #define mem(a) memset(a, 0, sizeof(a)) 19 #define rson m+1, r, rt<<1|1 20 #define mem1(a) memset(a, -1, sizeof(a)) 21 #define mem2(a) memset(a, 0x3f, sizeof(a)) 22 #define rep(i, n, a) for(int i = a; i<n; i++) 23 #define fi first 24 #define se second 25 typedef pair<int, int> pll; 26 const double PI = acos(-1.0); 27 const double eps = 1e-8; 28 const int mod = 1e9+7; 29 const int inf = 1061109567; 30 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 31 const int maxn = 2e4+5; 32 int sa[maxn]; 33 int t1[maxn],t2[maxn],c[maxn], a[maxn]; 34 int rankk[maxn],height[maxn]; 35 void build_sa(int s[],int n,int m) 36 { 37 int i,j,p,*x=t1,*y=t2; 38 for(i=0;i<m;i++)c[i]=0; 39 for(i=0;i<n;i++)c[x[i]=s[i]]++; 40 for(i=1;i<m;i++)c[i]+=c[i-1]; 41 for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i; 42 for(j=1;j<=n;j<<=1) 43 { 44 p=0; 45 for(i=n-j;i<n;i++)y[p++]=i; 46 for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; 47 for(i=0;i<m;i++)c[i]=0; 48 for(i=0;i<n;i++)c[x[y[i]]]++; 49 for(i=1;i<m;i++)c[i]+=c[i-1]; 50 for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; 51 swap(x,y); 52 p=1;x[sa[0]]=0; 53 for(i=1;i<n;i++) 54 x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; 55 if(p>=n)break; 56 m=p; 57 } 58 } 59 void getHeight(int s[],int n) 60 { 61 int i,j,k=0; 62 for(i=0;i<=n;i++)rankk[sa[i]]=i; 63 for(i=0;i<n;i++) 64 { 65 if(k)k--; 66 j=sa[rankk[i]-1]; 67 while(s[i+k]==s[j+k])k++; 68 height[rankk[i]]=k; 69 } 70 } 71 int check(int mid, int n) { 72 int maxx = sa[1], minn = sa[1]; 73 for(int i = 2; i<=n; i++) { 74 if(height[i]<mid) { 75 minn = maxx = sa[i]; 76 } else { 77 minn = min(minn, sa[i]); 78 maxx = max(maxx, sa[i]); 79 if(maxx-minn>mid) 80 return 1; 81 } 82 } 83 return 0; 84 } 85 int main() 86 { 87 int n, m; 88 while(cin>>n&&n) { 89 for(int i = 0; i<n; i++) 90 scanf("%d", &a[i]); 91 for(int i = 0; i<n-1; i++) { 92 a[i] = a[i] - a[i+1] + 90; 93 } 94 a[n--] = 0; 95 build_sa(a, n+1, 190); 96 getHeight(a, n); 97 int l = 1, r = n/2; 98 while(l<=r) { 99 int mid = l+r>>1; 100 if(!check(mid, n)) { 101 r = mid-1; 102 } else { 103 l = mid+1; 104 } 105 } 106 if(l<5) { 107 l = 0; 108 } 109 cout<<l<<endl; 110 } 111 return 0; 112 }
标签:
原文地址:http://www.cnblogs.com/yohaha/p/5097464.html