Codeforces 题面传送门 & 洛谷题面传送门

事实证明,有的难度评分不算很高、涉及的知识点不算很难的题目也能出得非常神仙

首先考虑如何暴力求答案。注意到一个文本串 \(T\) 在 \(s_k\) 中出现的位置,有两种可能,要么跨过中间的 \(t_k\),要么没跨过,前者等价于文本串在 \(s_{k-1}[|s_{k-1}|-|T|+2,|s_{k-1}|]+t_k+s_{k-1}[1,|T|-1]\) 中出现的次数。由于其长度为 \(\mathcal O(|T|)\),因此可以在 KMP 或哈希在 \(\mathcal O(|T|)\) 时间内求出。要么没有跨过中间的 \(t_k\),而这样的出现位置要么在 \(s_0\) 中出现过,要么在某个 \(s_{k'}(k'<k)\) 中作为跨过中间的 \(t_{k'}\) 的字符串出现。因此

\[res=\text{occ}(t_0,T)·2^k+\sum\limits_{i=1}^k\text{occ}(s_{i}[|s_{i}|-|T|+2,|s_{i}|]+t_i+s_{i}[1,|T|-1],T)·2^{k-i}
\]

其中 \(\text{occ}(s,t)\) 表示 \(t\) 在 \(s\) 中的出现次数。

考虑优化。我们找到最小的 \(k'\),满足 \(|t_{k'}|>|T|\),如果不存在这样的 \(k'\) 或 \(k'>k\) 则直接输出 \(\text{occ}(t_k,T)\) 即可。否则我们先令答案加上 \(\text{occ}(t_{k'},T)·2^{k-k'}\),而对于 \(i>k',j>k'\),由于 \(|T|<|s_i|,|T|<|s_j|\),如果 \(t_i=t_j\),那么显然有 \(s_{i}[|s_{i}|-|T|+2,|s_{i}|]+t_i+s_{i}[1,|T|-1]=s_{j}[|s_{j}|-|T|+2,|s_{j}|]+t_j+s_{j}[1,|T|-1]\),我们考虑枚举所有 \(t_j=c\),计算 \(\text{occ}(s_{i}[|s_{i-1}|-|T|+2,|s_{i}|]+c+s_{i}[1,|T|-1],T)\),然后前缀和求出 \(\sum\limits_{i=k'+1}^k2^{-i}[t_i=c]\),这样即可在 \(|T|·|\Sigma|\) 的时间内算出答案。

时间复杂度 \(\Theta((\sum|T|+n)·|\Sigma|)\)

const int MAXN=1e5;
const int MAXM=100;
const int MAXL=1e6;
const int BS=191;
const int MOD=1e9+7;
const int INV2=5e8+4;
const int HMOD=1004535809;
int n,qu,occ[MAXN+5][28],pw[MAXN+5],ipw[MAXN+5],pw_hs[MAXL+5];
char s[MAXM+5],t[MAXN+5];string str[22];
int getocc(string s,string t){
static int hss[MAXL*2+5];int hst=0,res=0;
for(int i=1;i<=s.size();i++) hss[i]=(1ll*hss[i-1]*BS+s[i-1])%HMOD;
for(int i=0;i<t.size();i++) hst=(1ll*BS*hst+t[i])%HMOD;
for(int i=0;i+t.size()<=s.size();i++)
if((hss[i+t.size()]-1ll*pw_hs[t.size()]*hss[i]%HMOD+HMOD)%HMOD==hst)
res++;
return res;
}
int main(){
scanf("%d%d%s%s",&n,&qu,s+1,t+1);
for(int i=(pw[0]=ipw[0]=1);i<=MAXN;i++){
ipw[i]=1ll*ipw[i-1]*INV2%MOD;
pw[i]=(pw[i-1]<<1)%MOD;
}
for(int i=(pw_hs[0]=1);i<=MAXL;i++) pw_hs[i]=1ll*pw_hs[i-1]*BS%HMOD;
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++) occ[i][j]=occ[i-1][j];
occ[i][t[i]-'a']=(occ[i][t[i]-'a']+ipw[i])%MOD;
}
int len=strlen(s+1),cur=0;for(int i=1;i<=len;i++) str[0].pb(s[i]);
while(str[cur].size()<=MAXL&&cur<n){
cur++;
for(int i=0;i<str[cur-1].size();i++) str[cur].pb(str[cur-1][i]);
str[cur].pb(t[cur]);
for(int i=0;i<str[cur-1].size();i++) str[cur].pb(str[cur-1][i]);
}
while(qu--){
int k;string p;static char buf[MAXL+5];
scanf("%d%s",&k,buf+1);int L=strlen(buf+1);
for(int i=1;i<=L;i++) p.pb(buf[i]);
int mx=0;while(str[mx].size()<=L) mx++;
if(k<=mx){printf("%d\n",getocc(str[k],p));continue;}
int res=1ll*getocc(str[mx],p)*pw[k-mx]%MOD;
for(int i=0;i<26;i++){
string nw_s;
for(int j=str[mx].size()-L+1;j<str[mx].size();j++) nw_s.pb(str[mx][j]);
nw_s.pb(i+'a');
for(int j=0;j<L-1;j++) nw_s.pb(str[mx][j]);
int msk=occ[k][i],cnt=getocc(nw_s,p);
// printf("%d %d\n",msk,cnt);
// cout<<nw_s<<" "<<p<<endl;
for(int j=1;j<=mx;j++) if(t[j]-'a'==i) msk=(msk-ipw[j]+MOD)%MOD;
res=(res+1ll*msk*pw[k]%MOD*cnt)%MOD;
} printf("%d\n",res);
}
return 0;
}

Codeforces 1466G - Song of the Sirens(哈希)的更多相关文章

  1. Codeforces Gym 100338B Spam Filter 字符串哈希+贝叶斯公式

    原题链接:http://codeforces.com/gym/100338/attachments/download/2136/20062007-winter-petrozavodsk-camp-an ...

  2. 【CodeForces】961 F. k-substrings 字符串哈希+二分

    [题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} ...

  3. Codeforces 542D Superhero's Job 数论 哈希表 搜索

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF542D.html 题目传送门 - CF542D 题目传送门 - 51Nod1477 题意 定义公式 $J(x ...

  4. Codeforces Round #543 (Div. 2) F dp + 二分 + 字符串哈希

    https://codeforces.com/contest/1121/problem/F 题意 给你一个有n(<=5000)个字符的串,有两种压缩字符的方法: 1. 压缩单一字符,代价为a 2 ...

  5. Codeforces 1182D Complete Mirror [树哈希]

    Codeforces 中考考完之后第一个AC,纪念一下qwq 思路 简单理解一下题之后就可以发现其实就是要求一个点,使得把它提为根之后整棵树显得非常对称. 很容易想到树哈希来判结构是否相同,而且由于只 ...

  6. Codeforces 356E - Xenia and String Problem(哈希)

    Codeforces 题面传送门 & 洛谷题面传送门 首先显然一个 gray 串的长度只可能是 \(2^k-1\),其中 \(k\in\mathbb{Z}\). 考虑将一个字符改成另外一个字符 ...

  7. Codeforces 961F - k-substrings(二分+哈希)

    Codeforces 题面传送门 & 洛谷题面传送门 介绍一种奇怪的 \(\Theta(n\log n)\) 的奇怪做法. 注意到这个"border 的长度必须是奇数"的条 ...

  8. Codeforces 1340F - Nastya and CBS(分块+哈希)

    Codeforces 题面传送门 & 洛谷题面传送门 首先看到这样的数据范围我们可以考虑分块,具体来说,对于每一块我们记录其中的括号是否能完全消掉,以及对其进行括号相消之后的括号序列(显然是一 ...

  9. Codeforces 109D String Transformation 字符串 哈希 KMP

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF109D.html 题目传送门 - CF109D 题意 给定两个字符串 $a,b$ ,求一组 $i,j$ 使得 ...

随机推荐

  1. tcl概述

    tcl,全名tool command language,是一种通用的工具语言. 1)每个命令之间,通过换行符或者分号隔开: 2)tcl的每个命令包含一个或者多个单词,默认第一个单词表示命令,第二个单词 ...

  2. 提高微信小程序的应用速度

    一.是什么 小程序启动会常常遇到如下图场景: 这是因为,小程序首次启动前,微信会在小程序启动前为小程序准备好通用的运行环境,如运行中的线程和一些基础库的初始化 然后才开始进入启动状态,展示一个固定的启 ...

  3. 每日一题,是否存在(c语言)

    每日一题:1.是否存在 是否存在描述猫咪非常喜欢饼干,尤其是字母饼干.现在,她得到一些字母饼干,她希望选择他们中的一些拼写某些单词. 你的任务是确定她是否可以拼出自己想要的单词. 输入输入包含若干测试 ...

  4. better-scroll快速上手及封装(vue项目)

    愿你有诗有梦,有坦荡荡的远方 本文声明:这是一篇学习coderwhy老师的vue2课程的一个笔记,所以本文章是在vue项目中实现,没学过vue的大佬们可以举一反三. 使用场景及介绍 BetterScr ...

  5. BUAA 2020 软件工程 个人项目作业

    BUAA 2020 软件工程 个人项目作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 ...

  6. STM32的I2C框图详解及通讯过程

    STM32 的I2C 特性及架构 如果我们直接控制STM32 的两个GPIO 引脚,分别用作SCL 及SDA,按照上述信号的时序要求,直接像控制LED 灯那样控制引脚的输出(若是接收数据时则读取SDA ...

  7. SpringCloud微服务实战——搭建企业级开发框架(九):使用Nacos发现、配置和管理微服务

    Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台,Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置 ...

  8. linked-list-cycle-ii leetcode C++

    Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Follo ...

  9. hdu 1754 I Hate It(单点更新,区段查最值)

    题意: N个成绩.M个操作. Q a b:查询第a个到第b个成绩中最高成绩 U a b:将第a个成绩改成b 思路: 看代码,, 代码: const int maxn = 200010; int max ...

  10. hdu 1158 Employment Planning(DP)

    题意: 有一个工程需要N个月才能完成.(n<=12) 给出雇佣一个工人的费用.每个工人每个月的工资.解雇一个工人的费用. 然后给出N个月所需的最少工人人数. 问完成这个项目最少需要花多少钱. 思 ...