51nod 1752 哈希统计
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 哈希统计的更多相关文章
- 51nod 1779逆序对统计(状压DP)
按照插入数的大小排序, 然后依次进行dp. 用一个状态表示n个数是否被选了 10110 就是表示第1.3.4个位置都选了 那么如果此时这个数该填到5这个位置,那么必定会造成一个逆序(因为下一个数会填到 ...
- 51Nod 快速傅里叶变换题集选刷
打开51Nod全部问题页面,在右边题目分类中找到快速傅里叶变换,然后按分值排序,就是本文的题目顺序. 1.大数乘法问题 这个……板子就算了吧. 2.美妙的序列问题 长度为n的排列,且满足从中间任意位置 ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- LeetCode 350: 两个数组的交集 II Intersection of Two Arrays II
题目: 给定两个数组,编写一个函数来计算它们的交集. Given two arrays, write a function to compute their intersection. 示例 1: 输 ...
- LeetCode:137. 只出现一次的数字 II
LeetCode:137. 只出现一次的数字 II 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. ...
- 用Hash Table(哈希散列表)实现统计文本每个单词重复次数(频率)
哈希表在查找方面有非常大应用价值,本文记录一下利用哈希散列表来统计文本文件中每个单词出现的重复次数,这个需求当然用NLP技术也很容易实现. 一.基本介绍 1.Hash Key值:将每个单词按照字母组成 ...
- 51Nod 1282 时钟 —— 最小表示法 + 字符串哈希
题目链接:https://vjudge.net/problem/51Nod-1282 1282 时钟 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难 ...
- 51nod 1267:4个数和为0 哈希
1267 4个数和为0 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给出N个整数,你来判断一下是否能够选出4个数,他们的和为0,可以则输出&qu ...
- 51Nod 算法马拉松28 B题 相似子串 哈希
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - 51Nod1753 题意概括 两个字符串相似定义为: 1.两个字符串长度相等 2.两个字符串对应位置上有且仅有 ...
随机推荐
- 阿尔法冲刺——Postmortem会议
设想与目标 1.我们软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 这个问题,我们觉得我们的软件目标还是比较明确的,在SRS中也给出了典型用户和典型场景的清晰的描述. 2 ...
- 冲刺NO.10
Alpha冲刺第十天 站立式会议 项目进展 项目核心功能逐步构建完成,测试工作也已开始.主要对部分功能组合进行测试以测试系统可用性. 问题困难 项目的主要困难在这个时间点主要存在于测试工作中,测试工作 ...
- 结对编程作业——四则运算GUI程序
毛忠庆 201421122088 赵嘉楠 201421122065 源代码存放位置:https://gitee.com/ouwen0819/SiZeYunSuan.git 题目描述 使用 -n 参数控 ...
- 《Language Implementation Patterns》之 解释器
前面讲述了如何验证语句,这章讲述如何构建一个解释器来执行语句,解释器有两种,高级解释器直接执行语句源码或AST这样的中间结构,低级解释器执行执行字节码(更接近机器指令的形式). 高级解释器比较适合DS ...
- 《Language Implementation Patterns》之 数据聚合符号表
本章学习一种新的作用域,叫做数据聚合作用域(data aggregate scope),和其他作用域一样包含符号,并在scope tree里面占据一个位置. 区别在于:作用域之外的代码能够通过一种特殊 ...
- 【iOS】swift 保持代码优美的10个方法
这篇Swift风格指南与你看到的其他的指南有所不同,此篇指南主要焦点集中在打印和Web展示的可读写上.我们创建此篇风格指南的目的,是为了让我们的图书.教程以及初学者套件中的代码保持优美和一致,即使我们 ...
- 扩展Microsoft Graph数据结构 - 架构扩展
前言 此前我有一篇 文章 讲解了Microsoft Graph的一种数据扩展技术-- 开发扩展(Open Extensions),它可以实现在支持的对象(例如用户,组等)上面附加任意的数据.但开放扩展 ...
- dubbo的InvocationChain
个人觉得dubbo比较好的设计是:一个是Cooma微容器设计.另一个就是InvocationChain了 Cooma微容器是自己实现了一套SPI,方便了用户做扩展: InvocationChain类似 ...
- jquery 实时监听输入框值变化方法
$('.offers-number').bind('input propertychange', function (a, b) { var value = $(this).val() if (!va ...
- SpringCloud的应用发布(二)vmvare+linux,Centos7.0下发布应用
一.运行环境 1.jdk下载安装 地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 检查是否有老版本jdk 如 ...