很有趣的一道题

这道题提议很难懂,其实就是让你求合法的集合数目。合法的集合定义为:

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】的更多相关文章

  1. 【system.string】使用说明

    对象:system.string 说明:提供一系列针对字符串类型的操作 目录: 方法 返回 说明 system.string.isBlank( string ) [True | False]  检测参 ...

  2. 【实用类String】String类方法的应用案例:查找判断指定字符出现的次数和位置

    一.应用要求 输入一个字符串,再输入要查找的字符,判断该字符在该字符串中出现的次数. 二.实现思路 1.使用substring()方法将字符串的每个字符存入数组 2.比较数组每个字符是否与指定的字符相 ...

  3. 【Scramble String】cpp

    题目: Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty subs ...

  4. 【Interleaving String】cpp

    题目: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given: ...

  5. 题解 CF1385D 【a-Good String】

    题意 定义:字符串s 为一个c-好串(c 为一个字符)时,必须满足: 当\(|s| = 1\) ,\(s = c\) 当\(|s| > 1\), \(s\) 的左半部分为全为 \(c\),右半部 ...

  6. 题解 CF1354B 【Ternary String】

    题意 给出一个字符串,只包含 \({1,2}\) 或 \({3}\) .从中找出一个长度最短的子串,要求至少包含 \({1,2,3}\) 各一次,并输出其长度. 输入格式 本题有多组测试数据 第一行一 ...

  7. 【wx:for】小程序列表渲染的使用说明

    wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件. 默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item,即: {{index}} . {{it ...

  8. 【废弃中】JavaScript 式与运算符

    创建: 2017/09/25 更新: 2019/01/14 修改标题 [JavaScript 式与运算符] ->  [JavaScript 式与主要Object的方法] 更新: 2019/02/ ...

  9. 【动态规划】【最短路】Codeforces 710E Generate a String

    题目链接: http://codeforces.com/problemset/problem/710/E 题目大意: 问写N个字符的最小花费,写一个字符或者删除一个字符花费A,将当前的字符数量翻倍花费 ...

随机推荐

  1. Python 数据分析1

    本节概要 基础环境 ipython基础 前言 这是18年的第一篇blog,因为boss对于我的工作上的一些期望,需要着手做一些数据分析的工作,所以开始撰写这个系列的blog.分类的内的主要内容基本都是 ...

  2. Javascript入门(二)变量、获取元素、操作元素

    一.变量 Javascript 有五种基本数据类型 number.String.boolean.undefined.null 一种复合类型:object 二.使用getElementById方法获取元 ...

  3. 修复服务器上出现ImportError: cannot import name main的问题

    在服务器上成功升级pip2之后再运行pip2命令出现如下报错信息 Traceback (most recent call last): File "/usr/bin/pip2.7" ...

  4. Photoshop CS6打开图片后看不到怎么办

    https://jingyan.baidu.com/album/54b6b9c0d45c632d583b4793.html

  5. MySQL用户授权【转】

    MySQL 赋予用户权限命令的简单格式可概括为:grant 权限 on 数据库对象 to 用户 一.grant 普通数据用户,查询.插入.更新.删除 数据库中所有表数据的权利. grant selec ...

  6. MySQL主从1205报错【转】

    主从报错1205 Slave SQL thread retried transaction 10 time(s) in vain, giving up. Consider raising the va ...

  7. sonar——Synchronized classes Vector, Hashtable, Stack and StringBuffer should not be used

    It is better to use their new unsynchronized replacements: ArrayList or LinkedList instead of Vector ...

  8. FreeSWITCH异常原因总结

    最经在玩FreeSWITCH的时候,遇到很多的问题,特此总结一下,希望以后不要犯类似的错误了: 1.Client端无法注册,但是FS运行正常? 解决办法:查看防火墙是否关闭./etc/init.d/i ...

  9. Java内置包装类

    Java内置包装类有Object.Integer.Float.Double.Number.Charcter.Boolean.Byte.System. Number,是抽象类,也是超类(父类).Numb ...

  10. Boostrap轮图片可以左右滑动

    记得引用Boostrap的js和css html代码: <div id="Mycarousel" class="carousel slide col-md-12&q ...