## BZOJ4698 差分 + 二分 + SA

https://www.lydsy.com/JudgeOnline/problem.php?id=4698

```#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int N,M,K;
int str[maxn],id[maxn];
int a[maxn],Height[maxn];
int tax[maxn],tp[maxn],sa[maxn],rak[maxn];
void Qsort(){
for(int i = 0; i <= M; i ++) tax[i] = 0;
for(int i = 1; i <= N ; i ++) tax[rak[i]]++;
for(int i = 1; i <= M ; i ++) tax[i] += tax[i - 1];
for(int i = N; i >= 1 ; i --) sa[tax[rak[tp[i]]]--] = tp[i];
}
void SA(){
for(int i = 1; i <= N; i ++) rak[i] = str[i],tp[i] = i;
Qsort();
for(int w = 1,p = 0; p < N;w <<= 1, M = p){
p = 0;
for(int i = 1; i <= w; i ++) tp[++p] = N - w + i;
for(int i = 1; i <= N ; i ++) if(sa[i] > w) tp[++p] = sa[i] - w;
Qsort(); swap(tp,rak);
rak[sa[1]] = p = 1;
for(int i = 2; i <= N ; i ++){
rak[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + w] == tp[sa[i - 1] + w])?p:++p;
}
}
}
void Get_Height(){
int k = 0,j;
for(int i = 1; i <= N; i ++){
if(k) k --;
int j = sa[rak[i] - 1];
while(str[j + k] == str[i + k]) k++;
Height[rak[i]] = k;
}
}
int Stack[maxn];
bool vis[maxn];
bool check(int x){
int top = 0;
int num = K;
for(int i = 1; i <= K; i ++) vis[i] = 0;
for(int i = 1; i <= N ; i ++){
if(Height[i] >= x){
if(!vis[id[sa[i]]]){
vis[id[sa[i]]] = 1;
Stack[++top] = id[sa[i]];
num--;
}
if(!vis[id[sa[i - 1]]]){
vis[id[sa[i - 1]]] = 1;
Stack[++top] = id[sa[i - 1]];
num--;
}
if(!num) return true;
}else{
for(int j = 1; j <= top; j ++) vis[Stack[j]] = 0;
top = 0;
num = K;
}
}
return false;
}
int solve(){
int l = 0,r = N - 1;
int ans = 0;
while(l <= r){
int m = l + r >> 1;
if(check(m)){
ans = m;
l = m + 1;
}else{
r = m - 1;
}
}
return ans + 1;
}
int main(){
Sca(K); N = 0;
M = 2000;
int MIN = INF;
for(int i = 1; i <= K ; i ++){
int x = read();
a[1] = read();
for(int j = 2; j <= x; j ++){
a[j] = read();
str[++N] = a[j] - a[j - 1];
MIN = min(MIN,a[j] - a[j - 1]);
id[N] = i;
}
str[++N] = ++M; id[N] = i;
}
if(MIN <= 0){
MIN = -MIN + 1;
for(int i = 1; i <= N ; i ++) str[i] += MIN;
M += MIN;
}
SA(); Get_Height();
Pri(solve());
return 0;
}```

0条评论