【2019 ICPC Latin American Regional】G.cutting pictures SAM

题意:给定一个串,然后有n个串,对每个串询问最少需要几个原串中的子串可以拼成目标串
分析:
对原串建立SAM,如果我们知道了目标串的前i位需要几个子串构成,记为dp[i],那么对于每个目标串,结果就是dp[lent],其中lent为每个目标串t的长度。那么转移很简单,dp[i] = dp[i-tmp]+1,其中tmp表示前i的字符组成的串的可以匹配的后缀的长度。
于是,对于每个串t,我们把每一位t[i]放在SAM中匹配即可…
详细的看代码应该能够理解。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
struct node
{
	int ch[26];
	int len,fa;
}point[maxn<<1];
int las = 1,tot = 1;
char s[maxn],t[maxn];
int dp[maxn<<1];
void add(char c)
{
	int p = las;
	int np = las = ++tot;
	point[np].len = point[p].len+1;
	for(;p && !point[p].ch[c];p=point[p].fa) point[p].ch[c] = np;
	if(!p) point[np].fa = 1;
	else
	{
		int q = point[p].ch[c];
		if(point[q].len==point[p].len+1) point[np].fa = q;
		else
		{
			int nq = ++tot;
			point[nq] = point[q];
			point[nq].len = point[p].len+1;
			point[q].fa = point[np].fa = nq;
			for(;p && point[p].ch[c]==q;p=point[p].fa) point[p].ch[c] = nq;
		}
	}
}
void gao()
{
	int lent = strlen(t+1);
	int p = 1,tmp = 0;
	for(int i=1;i<=lent;i++)
	{
		char x = t[i]-'A';
		if(point[p].ch[x]) p = point[p].ch[x],tmp++;
		else
		{
			while(!point[p].ch[x] && p) p = point[p].fa;
			if(!p) p = 1,tmp = 0;
			else 
			{
				tmp = point[p].len+1;
				//cout<<"i="<<i<<",tmp="<<tmp<<endl;
				p = point[p].ch[x];
			}
		}
		if(tmp==0)
		{
			printf("-1\n");
			return;
		}
		dp[i] = dp[i-tmp]+1;
	}
	printf("%d\n",dp[lent]);
	return;
}
int main()
{
	scanf("%s",s+1);
	int lens = strlen(s+1);
	for(int i=1;i<=lens;i++) add(s[i]-'A');
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%s",t+1);
		gao();
	}
	return 0;
}
/*
MONTEVIDEO
4
DEMONIO
MONTE
EDIT
WON

SANTIAGO
3
TITA
SANTIAGO
NAS

*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值