写了一下午,交了 20+ 发,10pts……
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+3;
int n,m,T,w,now,tot,a[N],sa[N],rk[N<<1],_rk[N<<1],id[N],cnt[N],height[N],sta[N],q;
bool vis[N];
stack<int>s;
void SA(){
m=114514;
for(int i=1;i<=n;i++) cnt[rk[i]=a[i]]++;
for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(int i=n;i;i--) sa[cnt[rk[i]]--]=i;
for(w=1;w<n;w<<=1,m=now){
now=0;
for(int i=n;i>n-w;i--) id[++now]=i;
for(int i=1;i<=n;i++) if(sa[i]>w) id[++now]=sa[i]-w;
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++) cnt[rk[id[i]]]++;
for(int i=1;i<=m;i++) cnt[i]+=cnt[i-1];
for(int i=n;i;i--) sa[cnt[rk[id[i]]]--]=id[i];
memcpy(_rk,rk,sizeof(rk));
now=0;
for(int i=1;i<=n;i++) rk[sa[i]]=now+=!(_rk[sa[i]]==_rk[sa[i-1]]&&_rk[sa[i]+w]==_rk[sa[i-1]+w]);
if(now>n) break;
}
for(int k=0,i=1;i<=n;i++){
if(k) k--;
while(a[i+k]==a[sa[rk[i]-1]+k]) k++;
height[rk[i]]=k;
}
}
bool check(int x){
while(!s.empty()) vis[s.top()]=0,s.pop();
for(int i=1;i<=n;i++){
if(height[i]<x) while(!s.empty()) vis[s.top()]=0,s.pop();
if(!vis[id[sa[i]]]){
vis[id[sa[i]]]=1;
s.push(id[sa[i]]);
if(s.size()>=T) return 1;
}
}
return 0;
}
int main(){
scanf("%d",&T); int qwq=1865;
for(int i=1;i<=T;i++){
int x,lst=0; scanf("%d",&x);
while(x--){
int y; scanf("%d",&y);
a[++n]=y-lst; lst=y;
}
a[++n]=qwq++;
}
SA();
int l=0,r=n,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) l=mid+1,ans=mid;
else r=mid-1;
}
printf("%d",ans+1);
}
求调。