博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu6153
阅读量:6345 次
发布时间:2019-06-22

本文共 1377 字,大约阅读时间需要 4 分钟。

题意

给出两个字符串,询问第二个字符串的所有后缀串在第一个字符串中的出现次数。

分析

将两个字符串逆序存储,将第二个字符串作为模板串,对第一个串进行 \(KMP\) ,开一个数组 \(cnt\) 记录模板串每一个前缀串的个数,最后用 \(fail\) 数组去更新下 \(cnt\) 数组。

code

#include
using namespace std;typedef long long ll;const ll MOD = 1e9 + 7;const int MAXN = 1e6 + 10;char s1[MAXN], s2[MAXN];int fail[MAXN];int cnt[MAXN];void getFail(char T[]) { memset(fail, 0, sizeof fail); int len = strlen(T); fail[0] = -1; int i = 0, j = -1; while(i < len) { if(j == -1 || T[i] == T[j]) { i++; j++; fail[i] = j; } else { j = fail[j]; } }}ll solve(char S[], char T[]) { memset(cnt, 0, sizeof cnt); getFail(T); int i = 0, j = 0; int len = strlen(S); while(i < len) { if(j == -1 || S[i] == T[j]) { i++; j++; cnt[j]++; } else { j = fail[j]; } } ll ans = 0; int len2 = strlen(T); for(int i = len2; i > 0; i--) { cnt[fail[i]] += cnt[i]; } for(int i = 1; i <= len2; i++) { ans = (ans + 1LL * cnt[i] * i) % MOD; } return ans;}int main() { int T; scanf("%d", &T); while(T--) { scanf("%s%s", s1, s2); int l1 = strlen(s1), l2 = strlen(s2); reverse(s1, s1 + l1); reverse(s2, s2 + l2); printf("%lld\n", solve(s1, s2)); } return 0;}

转载于:https://www.cnblogs.com/ftae/p/7401646.html

你可能感兴趣的文章
CentOS 7 下安装 Nginx
查看>>
Spring Boot 自动配置之@EnableAutoConfiguration
查看>>
为了学习go我从0开始用beego写了一个简单个人博客(2)登陆管理
查看>>
职业女性:学会减压救自己!
查看>>
OSChina 周一乱弹 —— 这个需求很简单!
查看>>
OSChina 周一乱弹 —— 我当你是朋友,你却……
查看>>
[Android官方API阅读]___<Device Compatibility>
查看>>
如何写出好的产品需求文档(PRD)?
查看>>
Flex Chart
查看>>
Python中实用却不常见的小技巧
查看>>
012# Adempiere系统的贸易流程(一)
查看>>
(一)阅读器客户端开发实战_引言
查看>>
为何禁用MyBatis缓存
查看>>
手机安装 apk 出现“解析包时出现问题”
查看>>
Oracle用户被锁定解决方法
查看>>
485总线的概念
查看>>
我的友情链接
查看>>
web前端笔记
查看>>
import 路径
查看>>
使用optimizely做A/B测试
查看>>