BZOJ4698 Sdoi2008 Sandy的卡片
阿新 • • 發佈:2018-12-22
傳送門
轉化題意可以得到 我們求得就是 所有串的差分串的LCS
SAM水過就好啦
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #define inf 20021225 #define ll long long #define mxn 110 using namespace std; struct edge{int to,lt;}e[mxn*4]; int in[mxn*4],cnt; struct node{int fa,len;map<int,int> mp;}t[mxn*4]; int poi,rt,lt,ch[mxn],n; int mx[mxn*4],mn[mxn*4]; void add(int x,int y) { e[++cnt].to=y;e[cnt].lt=in[x];in[x]=cnt; } void pre(){rt=lt=++poi;memset(mn,48,sizeof(mn));} void insert(int c) { int p=lt, np=lt=++poi; t[np].len=t[p].len+1; for(;p&&!t[p].mp[c];p=t[p].fa) t[p].mp[c]=np; if(!p){t[np].fa=rt; return;} int q=t[p].mp[c]; if(t[q].len==t[p].len+1){t[np].fa=q;return;} int nq=++poi; t[nq].mp=t[q].mp; t[nq].len=t[p].len+1; t[nq].fa=t[q].fa; t[np].fa=t[q].fa=nq; for(;p&&t[p].mp[c]==q;p=t[p].fa) t[p].mp[c]=nq; } void build(){for(int i=2;i<=poi;i++) add(t[i].fa,i);} void init(){memset(mx,0,sizeof(mx));} void find() { int pos=rt,len=0; for(int i=1;i<=n;i++) { int tmp=ch[i]; if(t[pos].mp[tmp]) pos=t[pos].mp[tmp],len++; else { for(;pos&&!t[pos].mp[tmp];pos=t[pos].fa); if(!pos) pos=rt,len=0; else len=t[pos].len+1,pos=t[pos].mp[tmp]; } //printf("%d\n",len); mx[pos]=max(mx[pos],len); } } void dfs(int x) { for(int i=in[x];i;i=e[i].lt) { dfs(e[i].to); mx[x]=max(mx[x],min(mx[e[i].to],t[x].len)); } mn[x]=min(mn[x],mx[x]); } int a[mxn]; int main() { int T; scanf("%d",&T); for(int i=1;i<=T;i++) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(i>1) ch[i-1]=a[i]-a[i-1]; } n--; if(i==1) { pre(); for(int i=1;i<=n;i++) insert(ch[i]); build(); } else init(),find(),dfs(rt); } int ans=0; for(int i=1;i<=poi;i++) ans=max(ans,mn[i]); printf("%d\n",ans+1); return 0; }