CF 494B 【Obsessive String】
很有趣的一道题
这道题提议很难懂,其实就是让你求合法的集合数目。合法的集合定义为:
1、集合中的所有串都是s的子串,且互不重叠 2、集合中的所有串都含有子串t。
看到网上很多题解说要用kmp,但我就不用...
因为仅需进行一个字符串匹配,而hash是很好写的匹配啊
而且kmp的next指针在dp中并没有起到作用。
说一下主体思路吧:
设两个字符串为s,t,长度分别为l1,l2
首先我们在原串中查找所有的位置i,使s中以i为结尾的子串与t匹配
对于所有的位置i,标记flag[i]=1;
然后我们进行dp
设dp[i]表示以选取的所有集合中集合的最后一个元素的结尾均为i,开头为j(j不体现在状态中,1<=j<=i-l2+1)的所有方案数
那么答案就是∑(i=1~l1)dp[i]
接下来我们考虑转移
首先,对于某一位置,如果flag[i]=0,我们有:
dp[i]=dp[i-1]
原因:如果到这一位置没有匹配上,那么说明这个位置只能被包含在前一个状态中。
那么,如果flag[i]=1,怎么办?
我们考虑集合中元素的个数:
如果只有一个元素,那么由于flag[i]=1,说明i-l2+1~i与t是可以完全匹配的,所以从1到i-l2+1都可以作为这个元素的起点,所以方案数为i-l2+1
如果有两个以上元素,那么最后一个元素的起点就可以是2~i-l2+1
那么我们设这个起点是k
于是上一个元素的终点就可以是1~k-1
所以如果起点是k,总方案数就是∑(i=1~k-1)dp[i]
那这个东西就可以用一个前缀和s来维护
而由于终点可以是2~i-l2+1,所以一共的总方案数就是:
∑(i=2-i-l2+1)s[i-1]
也就是:
∑(i=1-i-l2)s[i]
发现这也是一个前缀和的形式,于是我们把s维护成一个前缀和ss
结合以上两个分析,得到转移为:
dp[i]=i-l2+1+ss[i-l2]
边递推边维护即可。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define seed 13131
#define ull unsigned long long
#define mode 1000000007
#define ll long long
using namespace std;
ll dp[100005];
ll s1[100005];
ll s2[100005];
char s[100005];
char t[100005];
ull has,has1[100005];
ull v;
bool flag[100005];
int main()
{
scanf("%s%s",s+1,t+1);
v=1;
int l1=strlen(s+1),l2=strlen(t+1);
for(int i=1;i<=l1;i++)
{
has1[i]=has1[i-1]*seed+s[i]-'a'+1;
}
v=1;
for(int i=1;i<=l2;i++)
{
has=has*seed+t[i]-'a'+1;
v*=seed;
}
for(int i=l2;i<=l1;i++)
{
int st=i-l2;
ull hast=has1[i]-has1[st]*v;
if(hast==has)
{
flag[i]=1;
}
}
for(int i=1;i<=l1;i++)
{
if(!flag[i])
{
dp[i]=dp[i-1];
}else
{
dp[i]=((i-l2+1)+s2[i-l2])%mode;
}
s1[i]=(s1[i-1]+dp[i])%mode;
s2[i]=(s2[i-1]+s1[i])%mode;
}
printf("%lld\n",s1[l1]);
return 0;
}
CF 494B 【Obsessive String】的更多相关文章
- 【system.string】使用说明
对象:system.string 说明:提供一系列针对字符串类型的操作 目录: 方法 返回 说明 system.string.isBlank( string ) [True | False] 检测参 ...
- 【实用类String】String类方法的应用案例:查找判断指定字符出现的次数和位置
一.应用要求 输入一个字符串,再输入要查找的字符,判断该字符在该字符串中出现的次数. 二.实现思路 1.使用substring()方法将字符串的每个字符存入数组 2.比较数组每个字符是否与指定的字符相 ...
- 【Scramble String】cpp
题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...
- 【Interleaving String】cpp
题目: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given: ...
- 题解 CF1385D 【a-Good String】
题意 定义:字符串s 为一个c-好串(c 为一个字符)时,必须满足: 当\(|s| = 1\) ,\(s = c\) 当\(|s| > 1\), \(s\) 的左半部分为全为 \(c\),右半部 ...
- 题解 CF1354B 【Ternary String】
题意 给出一个字符串,只包含 \({1,2}\) 或 \({3}\) .从中找出一个长度最短的子串,要求至少包含 \({1,2,3}\) 各一次,并输出其长度. 输入格式 本题有多组测试数据 第一行一 ...
- 【wx:for】小程序列表渲染的使用说明
wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件. 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item,即: {{index}} . {{it ...
- 【废弃中】JavaScript 式与运算符
创建: 2017/09/25 更新: 2019/01/14 修改标题 [JavaScript 式与运算符] -> [JavaScript 式与主要Object的方法] 更新: 2019/02/ ...
- 【动态规划】【最短路】Codeforces 710E Generate a String
题目链接: http://codeforces.com/problemset/problem/710/E 题目大意: 问写N个字符的最小花费,写一个字符或者删除一个字符花费A,将当前的字符数量翻倍花费 ...
随机推荐
- 【Thymeleaf】Thymeleaf模板对html实时刷新
解决方案 spring: thymeleaf: cache: false 修改完html代码后Ctrl+Shift+F9,重新编译即可刷新页面内容!
- XML解析技术-dom4j
- 20165234 《Java程序设计》第二周课下作业
1. 教材代码完成情况测试P14 把100改为自己的后四位学号,编译运行Kernighan.java 代码的功能是从给定一个数字,实现从1依次加到此数的和. 如下是我用命令行实现代码的编译与运行. 2 ...
- canves绘制北京地铁线路图,包括线路绘制,优先路线,单路径选择。
canves绘制北京地铁线路图,包括线路绘制,优先路线,单路径选择. 即将推出,后台涵盖各种语言,php,C#,java,nodejs等.
- QML 从入门到放弃 第二卷
第二卷如何更快速的放弃,注重的是C++和QML的交互 <1>记事本.. (1) 先测试下不在QML创建C++对象,仅仅在main.cpp添加一个属性函数供调用. 注意只使用槽函数来做到. ...
- LordPE修复从进程dump出来的内存文件
场景 应急响应中从进程发现被注入了EXE文件,通过processhacker的Memory模块dump出来注入的文件.PE修复后在IDA里反汇编查看这个恶意代码的功能是什么. 解决 LordPE 虚拟 ...
- 华为QUIDWAY系列路由器的负载均衡配置
作者:邓聪聪 华为系列路由器的负载均衡NQA联动侦测配置案例: 需求:该局域网,IP地址(末位奇数)走联通,IP地址(末位偶数)走电信当某个运营商不可达时,自动切换.通过NQA来确定运营商是否可达., ...
- input修改placeholder文字颜色
少废话,上代码: <style> input::-webkit-input-placeholder{ color:red; } input::-moz-placeholder{ /* Mo ...
- mybatis:在springboot中的配置
## Mybatis 配置 mybatis.type-aliases-package=com.xfind.core.entity.xianyu mybatis.mapper-locations=cla ...
- Light Oj 1005
题意: 从 n*n 的棋盘中放置 K 个 行和列不冲突的棋子 思路: 组合数学, 先选 k 个 行, k 个列, 就是 C(n,k) ^ 2; 然后 K 个棋子不相同, K ! 全排列 #includ ...