很有趣的一道题

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

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. sql-connectionStrings

    <connectionStrings> <add name="ClassReservatConnectionString" connectionString=&q ...

  2. java程序中默认浮点形值常量是什么类型的?如何区分不同类型的浮点型整数值常量?

    java程序中默认浮点形值常量是什么类型的 默认的所有的浮点型数值都是double型

  3. MySql 在cmd下的学习笔记 —— 有关多表查询的操作(内连接,外连接,交叉连接)

    mysql> create table test5( -> id int, ) -> )engine myisam charset utf8; Query OK, rows affe ...

  4. Informatic 使用过程中的问题

    1.database driver error ORA-12154 1)检查监听是否启动 2)是否在tnsnames.ora中配置

  5. Android 6.0系统动态请求系统相机权限

    private static final int TAKE_PHOTO_REQUEST_CODE = 1; public static String takePhoto(Context context ...

  6. 快速了解Hash算法

    hash hashcode java  1.hash 2.hash算法 1.hash Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射pre-image)通过 ...

  7. MFC调用libyara遇到的问题

    测试结果 如果调用yara非要变成共享DLL的形式,加那么多的DLL,不如直接调用EXE文件.反而依赖vcruntime运行库的DLL会少很多... 调用libyara 调用libraya和C++调用 ...

  8. boost 随机数发生器

    Random     随机数 在很多应用中都需要使用随机数.本库力求提供一个高效的,通用的随机数库.boost库有多种随机数生成方式.先熟悉一下各种随机数生成器的概念. 数字生成器(Number Ge ...

  9. Python调用subprocess.Popen卡死的解决方案

    转载自:https://www.cnblogs.com/keke-xiaoxiami/p/7875009.html 在Python中,调用:subprocess.Popen(cmd, stdout = ...

  10. DBUtils--数据库连接池

    介绍 DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装. pg大概是是PostgreSQL(基于PyGreSQL)数据库,DB是其他数据库 Steady[ ...