zoukankan      html  css  js  c++  java
  • BZOJ4698 Sdoi2008 Sandy的卡片

    传送门

    转化题意可以得到 我们求得就是 所有串的差分串的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
    ",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
    ",ans+1);
    	return 0;
    }
  • 相关阅读:
    [leetCode]剑指 Offer 36. 二叉搜索树与双向链表
    [leetCode]剑指 Offer 35. 复杂链表的复制
    剑指 Offer 34. 二叉树中和为某一值的路径
    剑指 Offer 33. 二叉搜索树的后序遍历序列
    剑指 Offer 32
    [leetCode]剑指 Offer 31. 栈的压入、弹出序列
    POJ
    POJ
    POJ
    POJ
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10321907.html
Copyright © 2011-2022 走看看