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
题意 给你n个乐符 让你差分以后找到最长不重复连续子串
做法 我们首先不能枚举答案 而是要二分
需要用height数组把大于二分时的mid值的数据放在一组 然后统计 其中sa的最大值和最小值 如果maxx-minn > mid 那么就是满足不重叠了
为什么要在一组呢?因为我们知道height数组是lcp数组 如果你想要最长公共连续子串 那么一定相邻的height数组里面找到这个最长公共连续子串的 注意二分上届应该是n+1 不然会出错
/*
if you can't see the repay
Why not just work step by step
rubbish is relaxed
to ljq
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;
const ll mod = (int)1e9+7;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
const int MAX_N = 3e4+5;
int wa[MAX_N],wb[MAX_N],wsf[MAX_N],wv[MAX_N],sa[MAX_N],n;
int Rank[MAX_N],height[MAX_N],s[MAX_N];
int str1[MAX_N],str2[MAX_N];
int cmp(int *r,int a,int b,int k)
{
return r[a]==r[b]&&r[a+k]==r[b+k];
}
void getsa(int *r,int *sa,int n,int m)//n为添加0后的总长
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=0; i<m; i++) wsf[i]=0;
for(i=0; i<=n; i++) wsf[x[i]=r[i]]++;
for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
for(i=n; i>=0; i--) sa[--wsf[x[i]]]=i;
p=1;
j=1;
for(; p<=n; j*=2,m=p)
{
for(p=0,i=n+1-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<=n; i++) wv[i]=x[y[i]];
for(i=0; i<m; i++) wsf[i]=0;
for(i=0; i<=n; i++) wsf[wv[i]]++;
for(i=1; i<m; i++) wsf[i]+=wsf[i-1];
for(i=n; i>=0; i--) sa[--wsf[wv[i]]]=y[i];
t=x;
x=y;
y=t;
x[sa[0]]=0;
for(p=1,i=1; i<=n; i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
}
}
void getheight(int *r,int n)//n为添加0后的总长
{
int i,j,k=0;
for(i=1; i<=n; i++) Rank[sa[i]]=i;
for(i=0; i<n; i++)
{
if(k)
k--;
else
k=0;
j=sa[Rank[i]-1];
while(r[i+k]==r[j+k])
k++;
height[Rank[i]]=k;
}
}
int main()
{
//ios::sync_with_stdio(false);
//freopen("a.txt","r",stdin);
//freopen("b.txt","w",stdout);
int t;
while(scanf("%d",&t)&&t)
{
n = 0;
for(int i = 1;i<=t;++i)
scanf("%d",&str1[i]);
for(int i = 2;i<=t;++i)
s[n++] = str1[i] - str1[i-1] + 89;
s[n] = 0;
getsa(s,sa,n,190);
getheight(s,n);
int l = 0,r = n+1,maxx = -1,minn = 2e4+5;
while(l<=r)
{
bool flag = false;
int mid = (l+r)>>1;
for(int i = 1;i<=n;++i)
{
if(height[i]>=mid)
{
maxx = max(maxx,max(sa[i],sa[i-1]));
minn = min(minn,min(sa[i],sa[i-1]));
}
else
{
if(maxx-minn >mid) flag = true;
minn = 2e4+5,maxx = -1;
}
}
if(maxx-minn>mid) flag = true;
if(flag) l = mid + 1;
else r = mid - 1;
}
if(r<4) printf("0\n");
else printf("%d\n",r+1);
}
//fclose(stdin);
//fclose(stdout);
//cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
return 0;
}