競プロ典型 90 問-难题

news/2025/11/5 23:15:21/文章来源:https://www.cnblogs.com/Jwe1/p/19194898

005倍增优化dp

题目大意(自己总结
只用数字 c1​,c2​,…,cK​ 可以构造出多少个 N 位正整数是 B 的倍数? 求除以 109+7 的余数。

  • $1 \leq K \leq 9$
  • $1 \leq c_1 \lt c_2 \lt \cdots \lt c_K \leq 9$
  • $1 \leq N \leq 10^{18}$
  • $2 \leq B \leq 1000$
    题目主要实现思路
    遇到这种凑倍数相关的题目,优先考虑dp[ i j ] 表示前i个数可以组成的数模上b的值,因此可得状态转移方程dp i (j * 10 + a[ k ])%b =dp i-1 j ,此时有三层循环N * B * K,因为N很大,所以考虑矩阵快速幂,可降到 O (B³×logN) ,引入一种新方法倍增法根据前面的递推公式dp[i + 1][(r × 10 + c[k]) % B] += dp[i][r],我们可以理解为从dp[0]开始,按dp[0]dp[1]dp[2]→…→dp[N]的顺序依次计算。但这种直接计算的方式需要 O (N) 步,效率过低。
    因此可以考虑先预处理出dp[ 1 ] dp 2 dp4 dp8 参考二进制的方式
    关键在于实现 “通过dp[i]数组和dp[j]数组,快速计算出dp[i+j]数组”。只要能实现这一点,我们就能像计算 3ⁿ那样,通过倍增法在 O (logN) 步内求出dp[N]数组。

这里的dp[i+j]表示 i+j 位整数对应的动态规划数组。我们可以将 i+j 位整数拆分为 “前 i 位” 和 “后 j 位” 两部分来分析:

  • 设前 i 位整数除以 B 的余数为 p(对应的数量为dp[i][p]种);
  • 设后 j 位整数除以 B 的余数为 q(对应的数量为dp[j][q]种)。

那么,由这两部分组成的 i+j 位整数除以 B 的余数为:(p × 10ʲ + q) % B

由此可推导出dp[i+j]的递推公式:dp[i + j][(p × tⱼ + q) % B] += dp[i][p] × dp[j][q]

其中,tⱼ表示 10ʲ除以 B 的余数。这正是 “通过dp[i]dp[j]计算dp[i+j]” 的递推公式,且该递推的时间复杂度为 O (B²)。

#include <bits/stdc++.h>#define int long longusing namespace std;const int N = 1e6 + 10;const int mod = 1e9 + 7;void solve(){    int n, b, k;    cin >> n >> b >> k;    vector<int> a(k, 0);    for (int i = 0; i < k; i++)    {        cin >> a[i];    }    auto mul = [&](vector<int> &dpi, vector<int> &dpj, int powv) -> vector<int>    {        vector<int> res(b, 0);        for (int p = 0; p < b; p++)        {            for (int q = 0; q < b; q++)            {                res[(p * powv + q) % b] += (dpi[p] * dpj[q]) % mod;                res[(p * powv + q) % b] = res[(p * powv + q) % b] % mod;            }        }        return res;    };    vector<int> tenpow(100, 0);    tenpow[0] = 10;    for (int i = 1; i < 100; i++)    {        tenpow[i] = (tenpow[i - 1] * tenpow[i - 1]) % b;    }    vector<vector<int>> fastdp(100, vector<int>(b, 0));    for (int i = 0; i < k; i++)    {        fastdp[0][a[i] % b] += 1;    }    for (int i = 1; i < 100; i++)    {        fastdp[i] = mul(fastdp[i - 1], fastdp[i - 1], tenpow[i - 1]);    }    vector<int> res(b, 0);    res[0] = 1;    for (int i = 0; i < 63; i++)    {        if ((n >> i) & 1)        {            res = mul(res, fastdp[i], tenpow[i]);        }    }    cout << res[0] << '\n';}signed main(){    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);    int T;    T = 1;    // cin >> T;    while (T--)        solve();    return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/957214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++函数调用的大致工作过程

c++函数调用的大致工作过程在C++中,函数调用是一个基本的编程概念,它允许我们将一组语句封装成一个独立的模块,以便重复使用或提高代码的可读性和可维护性。函数调用的工作过程可以分为以下几个步骤: 1、函数声明(…

Slack端到端测试管道优化:构建时间减半的技术实践

本文详细介绍了Slack开发体验团队如何通过条件性前端构建和预构建资产缓存策略,将端到端测试管道的构建时间从10分钟缩短至2分钟,显著提升开发效率并降低云存储成本。在 DevOps 和开发者体验(DevXP)领域,速度和效…

结构体与联合体的区别

1.内存分配方式 结构体为每一个结构体的成员分配独立的内存空间;总内存为所有成员大小之和。 联合体的成员共享同一片内存空间,总内存大小为最大成员的大小。 2.成员访问特性 结构体可以同时访问所有的成员 联合体同…

Day14综合案例二--

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">…

解决colcon编译卡死

下面这两个命令我这里不起作用:colcon build --parallel-workers 6 colcon build --executor sequential下面命令可以解决卡死问题:MAKEFLAGS=-j4 colcon build

铁杆粉丝占比20251105

序号 代码 名称 最新价(2025.11.05) 涨跌幅(2025.11.05) 铁杆粉丝占比 涨跌额(2025.11.05) 最高价(日线不复权)(2025.11.05) 最低价(日线不复权)(2025.11.05) 换手率(2025.11.05) 量比(2025.11.05) 成交量(股)(2025.11…

Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么? - Higurashi

基于:Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么?在 MyBatis 中,Executor 是一个关键的接口,负责执行映射的 SQL 语句。MyBatis 提供了四种类型的 Executor,每种 Executor 在执行 SQL 和处理事务方…

100小时学会SAP—问题10:ME51N提示物料XX的强制账户设置(输入账户设置类别)

100小时学会SAP—问题10:ME51N提示物料XX的强制账户设置(输入账户设置类别)执行事务码ME51N时,报错如下:物料XXXXXX的强制账户设置(输入账户设置类别)解决方法:SPRO-后勤常规-物料主数据-基本设置-物料类型-定义…

P8990 [北大集训 2021] 小明的树 题解

QwQP8990 [北大集训 2021] 小明的树 题解 首先刻画 “美丽”,考虑灭点,由于 1 始终灭,所以形如一个包含 1 的连通块,灭点连通块数量要为 1。 因为要刻画连通块数量,考虑点减边容斥,即连通块个数是灭点个数减 “灭…

100小时学会SAP—问题11:MIGO收货时报错不可能为条目BSX CN01确立账户

100小时学会SAP—问题11:MIGO收货时报错不可能为条目BSX CN01确立账户执行事务码MIGO收货时,报错如下:不可能为条目BSX CN01确立账户。解决方法: 1、首先按照100小时学会SAP步骤配置(在用MMR1、MMF1事务码创建物料…

【动态维护前 x 大元素】LeetCode 3321. 计算子数组的 x-sum II

View Post【动态维护前 x 大元素】LeetCode 3321. 计算子数组的 x-sum II题目 https://leetcode.cn/problems/find-x-sum-of-all-k-long-subarrays-ii/description/ 题解 定义两个有序集合 \(L, R\) 动态维护数组前 \(…

100小时学会SAP—问题8:财务凭证行项目BSEG及对应的六张表

100小时学会SAP—问题8:财务凭证行项目BSEG及对应的六张表FI会计模块中输入一笔业务将会记一个财务凭证,SAP系统中将凭证信息分为抬头信息和明细信息两部分加以存储。其中抬头(Header)信息存储在透明表BKPF中,明细(…

100小时学会SAP—问题9:MD03提示日期在有效工厂日历之后(请改正)

100小时学会SAP—问题9:MD03提示日期在有效工厂日历之后(请改正)执行事务码MD03时,报错如下:提示日期在有效工厂日历之后(请改正)解决方法:这是因为在创建工厂数据的时候工厂的日期没有更改造成的。 路径为:SP…

100小时学会SAP—问题6:创建采购收货时出现WE在年2025中编号不存在

100小时学会SAP—问题6:创建采购收货时出现WE在年2025中编号不存在前台 后勤—物料管理—库存管理—货物移动—收货—对采购订单—采购订单GR(MIGO) 报了如下错误:有关业务/事件类型WE在年2025的号码范围不存在解决…

100小时学会SAP—问题7:FB70提示过账码没有定义

100小时学会SAP—问题7:FB70提示过账码没有定义执行事务码FB70时,报错如下:Posting keys not defined原因:在文档“0528—FB70运行时提示在表T030B中AGD输入丢失”中,解决方法错误,其中的PK码自己瞎填,导致错误…

树剖

接dfs序。 https://www.cnblogs.com/ybjnb/p/19089551 树剖 (dfs序的性质依旧满足 即子树也是一段连续区间)将一颗树转化为一个序列 将树上任意一条路径转化成 log(n) 段连续区间 然后就可以用序列数据结构维护信息。…

100小时学会SAP—问题5:SAP导航菜单字体突然变小

100小时学会SAP—问题5:SAP导航菜单字体突然变小问题:SAP导航菜单字体突然变小 无论修改字体、字符集或登录其他服务器的SAP都是菜单字体变小解决方法: 删除注册表(regedit)HKEY_CURRENT_USER\Software\SAP\SAPGU…

如何降低大模型幻觉

目录数据层面的改进检索增强生成(RAG)提示工程优化强化学习与人类反馈多模型验证置信度校准事实核查层特定领域微调 在大模型开发中减少幻觉是一个核心挑战。以下是一些有效的策略: 数据层面的改进 高质量的训练数据…

11月5日---学习总结

一、内存四区 代码区|全局区|栈区|堆区 1.程序运行前(生成可执行程序exe,未执行该程序之前) 1.1 代码区: *特点1:只读:不可修改 *特点2:共享:防止频繁使用占用内存 1.2全局区:全局变量、静态变量、常量 *静态…