【Codechef DEVLOCK Devu and Locks】【倍增二维FFT】

博客分析了一道Codechef上的DEVLOCK问题,探讨如何利用倍增二维快速傅里叶变换(FFT)求解模p等于0且数字和不超过m的n位数的个数。通过分类数位的系数,计算每个系数出现的次数,并利用FFT进行高效计算,最终得出解决方案。文章详细阐述了算法思想和实现过程,时间复杂度为O(pmlognlogm+p2mlogm+p3m)。
摘要由CSDN通过智能技术生成

题意

求有多少个 n n n位十进制数(可以有前导零),满足模 p p p等于 0 0 0且各位数字之和不超过 m m m
n ≤ 1 0 9 , p ≤ 16 , m ≤ 15000 n\le 10^9,p\le 16, m\le 15000 n109,p16,m15000

分析

注意到第 i i i位贡献的系数为 1 0 i   m o d   p 10^i\bmod p 10imodp,两位的贡献不同当且仅当对应系数不同。因此可以把数位按照系数分类。设 n u m i num_i numi表示有多少位满足贡献系数为 i i i n u m i num_i numi可以通过求 1 0 k 10^k 10k p p p的周期来求出。

可以用倍增FFT求出 f i , j f_{i,j} fi,j表示选了 n u m i num_i numi 0 0 0 9 9 9之间的数,和为 j j j的方案数。显然 f i , j f_{i,j} fi,j的每种方案中,选取数字乘上对应系数之和模 p p p的值为 i j   m o d   p ij\bmod p ij

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值