CF1466G Song of the Sirens
题意简述:给出 \(n,s_0,t\ (n=|t|)\),定义 \(s_i=s_{i-1}+t_i+s_{i-1}\)。多次询问给出 \(k,m\),求 \(m\) 在 \(s_k\) 中的出现次数。记 \(L=\sum |m|\),则 \(L\leq 10^6\)。
Goodbye 2020 的 G。我当时怎么没做出来呢?
key observation:若 \(|m|\leq|s_i|\),那么答案可以分成两部分计算:
- 一部分是 \(m\) 完整地出现在 \(s_k\) 中的次数。那么根据 \(s\) 的定义,设 \(m\) 在 \(s_i\) 中出现了 \(f(m,s_i)\) 次,则 \(m\) 在 \(s_k\) 中出现了 \(2^{k-i}f(m,s_i)\) 次。这一点是显然的。
- 另一部分是 \(m\) 中有一个字符被 \(t_{i+1},t_{i+2},\cdots,t_k\) 的某个字符匹配,剩下来的前缀出现在 \(s_i\) 的后缀,后缀出现在 \(s_i\) 的前缀的次数之和。考虑 \(t\) 的某个位置 \(p\ (i<p\leq k)\) 上的字符 \(t_p\) 在 \(s_k\) 中被复制的次数(只考虑该位置 \(p\),而不考虑与 \(t_p\) 相同的其它位置上的字符),根据 \(s\) 的定义,它被复制了 \(2^{k-p}\) 次。枚举 \(m\) 中被匹配的位置 \(j\) 和 \(t[i+1:k]\) 中与 \(m_j\) 匹配的位置 \(p\),则贡献可以写成 \(\sum_{j=1}^{|m|}\sum_{p=i+1}^k2^{k-p}[m[1:j-1]=s_i[|s_i|-j+1:|s_i|]\land m_j=t_p\land m[j+1:r]=s_i[1:r-j]]\)。将其改写为 \(\sum_{j=1}^{|m|}[m[1:j-1]=s_i[|s_i|-j+1:|s_i|]\land m[j+1:r]=s_i[1:r-j]]\sum_{p=i+1}^k2^{k-p}[m_j=t_p]\)。注意到后面这坨东西在 \(i,k\) 确定的情况下,对于相同的 \(m_j\) 给出的答案是相同的。因为 \(m_j\) 的取值只有 \(26\) 种,那么预处理出来即可。
- 怎么预处理?注意到相同的 \(t_p\) 对于不同的 \(i,k\) 贡献可能不同,很讨厌。将其写为 \(\dfrac{\sum_{p=i+1}^n2^{n-p}[m_j=t_p]-\sum_{p=k+1}^n2^{n-p}[m_j=t_p]}{2^{n-k}}\),那么对于每个字符 \(c\),预处理出 \(g(c,i)=\sum_{p=i+1}^n2^{n-p}[t_p=c]\) 与 \(2\) 的幂的逆元,就可以 \(\mathcal{O}(1)\) 计算上式(\(\dfrac{g(m_j,i+1)-g(m_j,k+1)}{2^{n-k}}\))。即对于每个字符 \(c\) 和字符串编号 \(i\),预处理出在 \(t[i+1:n]\) 中所有与 \(c\) 相等的 \(t_p\) 在 \(s_n\) 中被复制的次数,就可以快速计算在 \(t[i+1:k]\) 中所有与 \(c\) 相等的 \(t_p\) 在 \(s_k\) 中被复制的次数。
思路 1:找到一个最小的 \(pos\) 使得 \(|s_{pos}|\geq \max(|m|)\)(如果不存在则为 \(n\))。对于每一个 \(j\in[0,pos]\),建出 \(s_j\) 的后缀数组,然后处理所有 \(k=j\) 的询问(若 \(j=pos\) 则处理所有 \(k\geq j\) 的询问)即可(SA 的主要作用是求出 \(m\) 在 \(s_i\) 中的出现次数)。判断 \(m,s\) 的前缀后缀是否相等需要用哈希。时间复杂度 \(\mathcal{O}(L\log L)\)。常数较大(而且我还写挂了)。
思路 2:在上面的思路中,对于一个询问,我们主要关注的是它的 \(k\)。这样在求出现次数的时候必须使用后缀数据结构(因为如果有很多 \(k\) 都很大而 \(|m|\) 很小的询问,同时有一个 \(|m|\) 很大的询问,那么直接哈希判断的复杂度可以达到 \(qL\)),比较麻烦。但是注意到对于那些 \(|m|\) 很小的询问,我们没有必要让它与 \(s_{pos}\) 匹配,直接找到一个最小的 \(i\) 满足 \(|s_i|\geq |m|\),让它与 \(s_i\) 匹配就好了。如果 \(i>k\) 则显然没有出现(因为 \(|s_k|<|m|\))。这样求出现次数就可以直接哈希或者 KMP 了,查询的时间复杂度可以降为 \(\mathcal{O}(L)\)。总时间复杂度即为 \(\mathcal{O}(n|\Sigma|+L)\)。
/*
Powered by C++11.
Author : Alex_Wei.
*/
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair <int,int>;
#define fi first
#define se second
#define mpi make_pair
#define pb emplace_back
#define mcpy(x,y) memcpy(x,y,sizeof(y))
const int L=2e6+5;
const int N=1e5+5;
const int mod=1e9+7;
void add(ll &x,int y){
x+=y; if(x>=mod)x-=mod;
}
ull hs1[L],hs2[L],p[L];
ull q1(int l,int r){
return hs1[r]-hs1[l-1]*p[r-l+1];
} ull q2(int l,int r){
return hs2[r]-hs2[l-1]*p[r-l+1];
}
int n,q,len,mxlen;
ll f[N][26],pw[N],iv[N],ans[N];
char s[L],t[N];
string qs[N];
vector <pii> qu[L];
int main(){
scanf("%d%d%s%s",&n,&q,s+1,t+1),pw[0]=p[0]=iv[0]=1;
for(int i=1;i<=n;i++)pw[i]=pw[i-1]*2%mod,iv[i]=iv[i-1]*(mod+1>>1)%mod;
for(int i=1;i<L;i++)p[i]=p[i-1]*131;
for(int i=n;i;i--){
for(int j=0;j<26;j++)f[i][j]=f[i+1][j];
add(f[i][t[i]-'a'],pw[n-i]);
} for(int i=1;i<=q;i++){
int id; cin>>id>>qs[i],mxlen=max(mxlen,(int)qs[i].size());
qu[qs[i].size()].pb(mpi(i,id));
} int pre=0,pos=0; len=strlen(s+1);
while(1){
for(int i=1;i<=len;i++)hs1[i]=hs1[i-1]*131+s[i];
for(int l=pre+1;l<=len;l++)for(pii it:qu[l]){
string t=qs[it.fi]; int id=it.fi,k=it.se,slen=t.size();
if(k<pos)continue;
for(int i=1;i<=slen;i++)hs2[i]=hs2[i-1]*131+t[i-1];
ull ap=0,hs=hs2[slen];
for(int i=slen;i<=len;i++)ap+=q1(i-slen+1,i)==hs;
ans[id]=ap*pw[k-pos]%mod;
for(int i=1;i<=slen;i++){
int l=i-1,r=slen-i,it=t[i-1]-'a';
if(q1(len-l+1,len)==q2(1,l)&&q1(1,r)==q2(slen-r+1,slen))
add(ans[id],(f[pos+1][it]-f[k+1][it]+mod)*iv[n-k]%mod);
}
} if(len>=mxlen)break;
for(int i=1;i<=len;i++)s[len+i+1]=s[i];
s[len+1]=t[++pos],pre=len,len=(len<<1)+1;
} for(int i=1;i<=q;i++)cout<<ans[i]<<"\n";
return 0;
}
CF1466G Song of the Sirens的更多相关文章
- Codeforces 1466G - Song of the Sirens(哈希)
Codeforces 题面传送门 & 洛谷题面传送门 事实证明,有的难度评分不算很高.涉及的知识点不算很难的题目也能出得非常神仙 首先考虑如何暴力求答案.注意到一个文本串 \(T\) 在 \( ...
- 读懂UI设计的心理学
好文转载,版权归原作者 作为UI设计师,对待用户就像对待婴儿,知道如何通过界面设计诱导用户非常重要,这就需要了解心理学方面的知识了.今天分享一篇日本设计师的好文,结合心理学与设计,教你读懂心理学,提高 ...
- UVA 590 二十一 Always on the run
Always on the run Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit ...
- python瓦登尔湖词频统计
#瓦登尔湖词频统计: import string path = 'D:/python3/Walden.txt' with open(path,'r',encoding= 'utf-8') as tex ...
- TWELP™ Vocoder
TWELP™ Vocoder DSP Innovations Inc. (DSPINI) announces new class of proprietary vocoders for wide ...
- How to Pronounce the Idiom: ‘Out Like a Light’
How to Pronounce the Idiom: ‘Out Like a Light’ Share Tweet Share Tagged With: Idioms English is full ...
- 哥谭第四季/全集Gotham迅雷下载
<哥谭>(Gotham)第三季刚刚结束,第四季首集的集名就公布了.<Pax Penguina>这个集名在拉丁语中意味着「Pax Romana」,也就是「罗马式的和平」(Roma ...
- Chapter 3 Phenomenon——9
"You were over there," I suddenly remembered, and his chuckle stopped short. “你之前不在这里”我突然记 ...
- [label][转载][web-design-psychology]网页设计心理
原文出处: http://mux.alimama.com/posts/1301 Tip1:信息不要同时全部展示,阶段性地向用户展示当前场景里必要的信息 设计师经常犯的错误:同时将大量信息展示给用户.不 ...
随机推荐
- 分库分表利器之Sharding Sphere(深度好文,看过的人都说好)
Sharding-Sphere Sharding-JDBC 最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现已更名为 S ...
- SpringCloud微服务实战——搭建企业级开发框架(四):集成SpringCloud+SpringBoot
1.在GitEgg工程的根目录,最上级父pom.xml文件中引入需要依赖的库及Maven插件,设置编码方式: <!--?xml version="1.0" encoding= ...
- Java基础-Java8新特性
一.Lambda表达式 在了解 Lambda 之前,首先回顾以下Java的方法. Java的方法分为实例方法,例如:Integer的equals()方法: public final class Int ...
- .net,C#,Vb,F#,Asp,Asp.net区别以及作用和方向
.net是平台,其他都是运行在其.NET FrameWork环境下的 C#,Vb都是语言运行在.net 平台下 Asp,Asp.net 都是用来写Web网页的,但是Asp和Asp.net有区别 Asp ...
- gson中TypeAdapter实现自定义序列化操作
最近在项目中遇到这么一个问题,我们后台需要向前端返回一个 json 数据,就是将一个地理位置对象以json的格式返回到前台,但是这个地理位置对象中的经纬度是Double数据类型,项目中规定,如果经纬度 ...
- [经验] 电源抑制比(PSRR)的测量原理及解决方法
PSRR(Power supply rejection ratio)又称电源抑制比,是衡量电路对于输入电源中纹波抑制大小的重要参数,表示为输出纹波和输入纹波的对数比,单位为分贝(dB)[1],其计算公 ...
- 洛谷 P5664 [CSP-S2019] Emiya 家今天的饭
链接: P5664 题意: 给出一个 \(n*m\) 的矩阵 \(a\),选 \(k\) 个格子(\(1\leq k\leq n\)),每行最多选一个,每列最多选\(⌊\dfrac k2⌋\) 个,同 ...
- shell IO重定向
I/O重定向 默认情况下,有3个"文件"处于打开状态,stdin,stdout,stderr:重定向的解释:捕捉一个文件,命令,程序,脚本或者脚本中的代码块的输出,然后将这些输出作 ...
- 笔记本加装SSD并装系统
1,首先了解笔记本配置信息 一般加装SSD都是120~256左右,并使用原有的机械硬盘:首先确定加装位置:1,是否支持M.2接口:假如支持,可以直接购买,拆机装上:我的笔记本不支持:所以考虑2,光驱的 ...
- PCIe知识摘要记录
摘: 一. 在PCIe的Spec中,并没有特别详细的关于Root Complex的定义,从实际的角度来讲,可以把Root Complex理解为CPU与PCIe总线系统通信的媒介.Endpoint处于P ...