Description

Solution

考虑用倍增来处理答案:

设 \(f[i][j]\) 表示长度恰好为 \(2^{i}\) 的哈希值为 \(j\) 的字符串的种数

\(dp[i][j]\) 表示长度小于等于 \(2^{i}\) 的哈希值为 \(j\) 的字符串的种数

容易得到转移式子:

\(f[i+1][j*base^{2^{i}}+k]=\sum f[i][j]*f[i][k]\)

\(dp[i+1][j*base^{2^{i}}+k]=dp[i][j*base^{2^{i}}+k]+\sum f[i][j]*dp[i][k]\)

发现两个转移是一个卷积的形式,\(NTT\) 优化转移即可

最后就是得到长度 \(<=n\) 的答案

可以像 \(dp\) 数组的求法一样,直接倍增求出即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200005,mod=998244353;
inline int qm(int x,int k){
int sum=1;
while(k){
if(k&1)sum=1ll*sum*x%mod;
x=1ll*x*x%mod;k>>=1;
}
return sum;
}
int L,R[N],inv,n,P,D,len,st[N],top=0,ans[N];ll b[N];
inline void init(){
for(n=1;n<=(P<<1);n<<=1)L++;
for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
inv=qm(n,mod-2);
}
inline void NTT(int *A,int o){
for(int i=0;i<n;i++)if(i<R[i])swap(A[i],A[R[i]]);
for(int i=1;i<n;i<<=1){
int t0=qm(3,(mod-1)/(i<<1)),x,y;
for(int j=0;j<n;j+=(i<<1)){
int t=1;
for(int k=0;k<i;k++,t=1ll*t0*t%mod){
x=A[j+k];y=1ll*A[i+j+k]*t%mod;
A[j+k]=(x+y)%mod;A[j+k+i]=(x-y+mod)%mod;
}
}
}
if(o==-1)reverse(A+1,A+n);
}
inline void mul(int *A,int *B){
NTT(A,1);NTT(B,1);
for(int i=0;i<=n;i++)A[i]=1ll*A[i]*B[i]%mod;
NTT(A,-1);
}
int f[20][N],dp[20][N],A[N],B[N];
inline void Modify(int i){
for(int j=0;j<n;j++)A[j]=B[j]=0;
for(int j=0;j<P;j++)A[j*b[i]%P]=(A[j*b[i]%P]+ans[j])%mod;
for(int j=0;j<P;j++)B[j]=(B[j]+f[i][j])%mod;
mul(A,B);
for(int j=0;j<P;j++)ans[j]=dp[i][j];
for(int j=0;j<n;j++)ans[j%P]=(ans[j%P]+1ll*A[j]*inv)%mod;
}
int main(){
freopen("pp.in","r",stdin);
freopen("pp.out","w",stdout);
cin>>len>>b[0]>>P>>D;
init();
for(int i='a';i<='z';i++)dp[0][i%P]++,f[0][i%P]++;
for(int i=0;(1<<(i+1))<=len;i++){
b[i+1]=b[i]*b[i]%P;
for(int j=0;j<n;j++)A[j]=B[j]=0;
for(int j=0;j<P;j++)A[j*b[i]%P]=(A[j*b[i]%P]+f[i][j])%mod;
for(int j=0;j<P;j++)B[j]=(B[j]+f[i][j])%mod;
mul(A,B);
for(int j=0;j<n;j++)f[i+1][j%P]=(f[i+1][j%P]+1ll*A[j]*inv)%mod; for(int j=0;j<n;j++)A[j]=B[j]=0;
for(int j=0;j<P;j++)A[j*b[i]%P]=(A[j*b[i]%P]+dp[i][j])%mod;
for(int j=0;j<P;j++)B[j]=(B[j]+f[i][j])%mod;
mul(A,B);
for(int j=0;j<n;j++)dp[i+1][j%P]=(dp[i+1][j%P]+1ll*A[j]*inv)%mod;
for(int j=0;j<P;j++)dp[i+1][j]=(dp[i+1][j]+dp[i][j])%mod;
}
for(int i=20;i>=0;i--)
if((1<<i)<=len)len-=(1<<i),st[++top]=i;
for(int i=0;i<P;i++)ans[i]=dp[st[top]][i];
while(--top)Modify(st[top]);
printf("%d\n",ans[D]);
return 0;
}

51nod 1752 哈希统计的更多相关文章

  1. 51nod 1779逆序对统计(状压DP)

    按照插入数的大小排序, 然后依次进行dp. 用一个状态表示n个数是否被选了 10110 就是表示第1.3.4个位置都选了 那么如果此时这个数该填到5这个位置,那么必定会造成一个逆序(因为下一个数会填到 ...

  2. 51Nod 快速傅里叶变换题集选刷

    打开51Nod全部问题页面,在右边题目分类中找到快速傅里叶变换,然后按分值排序,就是本文的题目顺序. 1.大数乘法问题 这个……板子就算了吧. 2.美妙的序列问题 长度为n的排列,且满足从中间任意位置 ...

  3. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  4. LeetCode 350: 两个数组的交集 II Intersection of Two Arrays II

    题目: 给定两个数组,编写一个函数来计算它们的交集. Given two arrays, write a function to compute their intersection. 示例 1: 输 ...

  5. LeetCode:137. 只出现一次的数字 II

    LeetCode:137. 只出现一次的数字 II 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. ...

  6. 用Hash Table(哈希散列表)实现统计文本每个单词重复次数(频率)

    哈希表在查找方面有非常大应用价值,本文记录一下利用哈希散列表来统计文本文件中每个单词出现的重复次数,这个需求当然用NLP技术也很容易实现. 一.基本介绍 1.Hash Key值:将每个单词按照字母组成 ...

  7. 51Nod 1282 时钟 —— 最小表示法 + 字符串哈希

    题目链接:https://vjudge.net/problem/51Nod-1282 1282 时钟 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难 ...

  8. 51nod 1267:4个数和为0 哈希

    1267 4个数和为0 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出&qu ...

  9. 51Nod 算法马拉松28 B题 相似子串 哈希

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - 51Nod1753 题意概括 两个字符串相似定义为: 1.两个字符串长度相等 2.两个字符串对应位置上有且仅有 ...

随机推荐

  1. 201621123057 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现什 ...

  2. 201621123068 作业07-Java GUI编程

    1. 本周学习总结 1.1 思维导图:Java图形界面总结 2.书面作业 1. GUI中的事件处理 1.1 写出事件处理模型中最重要的几个关键词. 注册.事件.事件源.监听 1.2 任意编写事件处理相 ...

  3. labview与单片机串口通信

    labview与单片机串口通信   VISA是虚拟仪器软件体系结构的缩写(即Virtual Instruments Software Architecture),实质上是一个I/O口软件库及其规范的总 ...

  4. Web前端性能分析

    Web前端性能通常上代表着一个完全意义上的用户响应时间,包含从开始解析HTML文件到最后渲染完成开始的整个过程,但不包括在输入url之后与服务器的交互阶段.下面是整个过程的各个步骤: 开始解析html ...

  5. codevs 1291 火车线路

    http://codevs.cn/problem/1291/ 题目描述 Description 某列火车行使在C个城市之间(出发的城市编号为1,结束达到的城市的编号为C),假设该列火车有S个座位,现在 ...

  6. Linux入门(1)_VMware和系统分区和系统安装和远程登陆管理

    1 VMware的安装和使用 注意有 快照 和 克隆 的功能. 快照相当于建立一个 系统还原点, 可以随时恢复到原来状态. 克隆功能可以复制一个和当前一样的系统,并可以选择链接安装,只使用很少的空间就 ...

  7. ( 转 ) CORS 有一次 OPTIONS 请求的原理

    刚接触前端的时候,以为HTTP的Request Method只有GET与POST两种,后来才了解到,原来还有HEAD.PUT.DELETE.OPTIONS-- 目前的工作中,HEAD.PUT.DELE ...

  8. 算法题丨4Sum

    描述 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...

  9. YML(2)yml 语法

    YAML 语法 来源:yaml 这个页面提供一个正确的 YAML 语法的基本概述, 它被用来描述一个 playbooks(我们的配置管理语言). 我们使用 YAML 是因为它像 XML 或 JSON ...

  10. Cookie、Session登陆验证相关介绍和用法

    一.Cookie和Session 首先.HTTP协议是无状态的:所谓的无状态是指每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应直接影响,也不会直接 ...