当前位置: 首页 > news >正文

P3002 [USACO10DEC] Threatening Letter G

形式化题意

给你两个串 \(s,t\),需要用最少的 \(s\) 的子串拼接出 \(t\),可重复使用。

思路

显然有一个贪心,从 \(t\) 的开头开始,每次尽可能长的匹配一段,直到将 \(t\) 匹配完成。

因为,如果放弃一个可以匹配的字符,让它参加到下一个子串的匹配,并不会使下次匹配的终点落在当前方案后面,这样在匹配次数相同的情况下,这种贪心的匹配长度最长。

然后,问题转化为,从 \(t\) 的某个字符开始,最长能与 \(s\) 的子串匹配多长。

这显然要用后缀数组。

考虑将 s+#+t 拼接在一起,处理出后缀数组和 h 数组。

对于 \(t\) 的每个位置,其与 \(s\) 子串匹配的最长方式一定是和 在 sa 数组中前或后第一个属于 s 的后缀 匹配。

前后扫两边 sa 数组,处理出 \(t\) 每个位置最长的匹配方式,直接贪心即可。

复杂度 \(O(n\log n)\) ,瓶颈为预处理后缀数组,当然用 sa-is 可以降到 \(O(n)\)

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,inf=1e9;int read(){int ans=0;char c=getchar();bool f=0;for(;!isdigit(c);c=getchar())if(c=='-')f=1;for(;isdigit(c);c=getchar())ans=(ans<<=1)+(ans<<2)+(c^48);return f?-ans:ans;
}void print(int x){if(x<0)x=-x,putchar('-');if(x>9)print(x/10);putchar(x%10|48);
}int n,m;
char s[N<<1];
int rk[N<<1],sa[N],id[N],cnt[N],oldrk[N<<1],h[N];void build(char *s,int n){int m=128;memset(cnt,0,(m+1)*sizeof(int));for(int i=1;i<=n;++i)cnt[rk[i]=s[i]]++;for(int i=1;i<=m;++i)cnt[i]+=cnt[i-1];for(int i=n;i>=1;--i)sa[cnt[rk[i]]--]=i;for(int w=1,p,cur;w<n;w<<=1){cur=0;for(int i=n-w+1;i<=n;++i)id[++cur]=i;for(int i=1;i<=n;++i)if(sa[i]>w)id[++cur]=sa[i]-w;memset(cnt,0,(m+1)*sizeof(int));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>=1;--i)sa[cnt[rk[id[i]]]--]=id[i];swap(rk,oldrk);p=0;for(int i=1;i<=n;++i){if(oldrk[sa[i]]==oldrk[sa[i-1]]&&oldrk[sa[i]+w]==oldrk[sa[i-1]+w])rk[sa[i]]=p;else rk[sa[i]]=++p;}m=p;if(m==n)break;}for(int i=1,p=0;i<=n;++i){if(rk[i]==1)continue;if(p)p--;while(s[i+p]==s[sa[rk[i]-1]+p])++p;h[rk[i]]=p;}
}char gc(){char c=getchar();while(c<'A'||c>'Z')c=getchar();return c;
}int val[N];signed main(){n=read();m=read();int cnt=0;for(int i=1;i<=n;++i)s[++cnt]=gc();s[++cnt]='#';for(int i=1;i<=m;++i)s[++cnt]=gc();build(s,cnt);for(int i=1,p=0,v=inf;i<=cnt;++i){v=min(v,h[i]);if(sa[i]<=n){p=i,v=inf;}else if(sa[i]>n+1){if(p)val[sa[i]-n-1]=v;}}for(int i=cnt,p=0,v=inf;i>=1;--i){if(sa[i]<=n){p=i,v=inf;}else if(sa[i]>n+1){if(p)val[sa[i]-n-1]=max(val[sa[i]-n-1],v);}v=min(v,h[i]);}int ans=0,p=1;while(p<=m){++ans;p+=val[p];}print(ans);putchar('\n');return 0;
}
http://www.jsqmd.com/news/408237/

相关文章:

  • 全球国际视野:工业AI智能体排名
  • 2026最新盘点:十大高清免费版权图片素材网站推荐,免费版权可商用 - 品牌2026
  • 好写作AI | 一句话翻来覆去说不清?AI帮你精炼语言,表达更精准
  • 2026年度中国荧光显微镜品牌厂家TOP5综合评估与选型指南 - 品牌推荐
  • 2026年聚氨酯发泡保温厂家联系电话推荐:专业选择与联系要点 - 品牌推荐
  • 2026最全 Java 面试八股文汇总(含答案解析)
  • 2026年荧光显微镜品牌厂家推荐:生产与科研场景深度评测,解决稳定性与数据痛点并附购买排名 - 品牌推荐
  • 好写作AI | 平时作业太多?分分钟搞定小论文和读后感!
  • 2026矿山行业振动监测系统优质产品推荐榜:无线振动传感器机构哪家强/振动传感器机构哪家好/振动监测系统公司/选择指南 - 优质品牌商家
  • 意义行为原生论:智能时代意义哲学的创造性建构——兼论其与中国传统知行智慧的会通
  • 2026水务行业振动监测系统优质推荐榜 - 优质品牌商家
  • 分析2026年服务不错的希腊移民机构,费用多少钱合适 - myqiye
  • 2026最新Adobe Stock中国区代理商精选,Adobe Stock中国区官网指引 - 品牌2026
  • MCPoison:Cursor中一个受信任的AI功能如何沦为黑客的后门(CVE-2025-54136)
  • 天猫超市卡回收,数字消费闭环标配 - 京回收小程序
  • 深入解析 FreeModbus 在嵌入式系统中的应用与数据流
  • ai提示词模板
  • FreeModbus 库移植指南:关键修改与注意事项
  • 信贷协商机构费用怎么选才最划算? - 代码非世界
  • 2026年金相显微镜品牌厂家推荐:高端制造与材料研发场景深度评测与权威排名发布 - 品牌推荐
  • 2026年石灰厂家最新推荐:熟石灰推荐、生石灰厂家推挤、生石灰推荐、石灰生产厂家推荐、罐装石灰厂家推荐选择指南 - 优质品牌商家
  • 深入解析 C 语言结构体位域:以 `AdcCtrl` 为例
  • 2026年度中国金相显微镜品牌厂家综合评估盘点 - 品牌推荐
  • 本科生收藏!千笔·降AI率助手,普遍认可的降AI率软件
  • 10人SolidWorks设计团队如何提升SolidWorks软件利用率
  • 信贷协商机构服务费用哪家更优惠?信贷协商服务费用,这样选才不吃亏! - 代码非世界
  • 2026年度中国金相显微镜品牌厂家TOP5综合评估与选型指南 - 品牌推荐
  • 动态漏洞库的进化:集成外部威胁情报与多源漏洞数据库,构建主动式防御情报中枢
  • PostgreSQL、StarRocks、Mysql区别
  • 负债后选信贷协商机构,哪家费用更优惠?过来人实测干货分享 - 代码非世界