博客
关于我
[SDOI2017]序列计数
阅读量:351 次
发布时间:2019-03-04

本文共 2256 字,大约阅读时间需要 7 分钟。

质数处理方法与动态规划转移方程

在动态规划问题中,某些转移方程的计算可能涉及质数的处理,这一部分的逻辑可以通过巧妙的数学变换来优化。以下是关于如何处理质数的具体方法以及动态规划中的转移方程实现。

动态规划转移方程与质数处理

在某些动态规划问题中,我们需要处理一个复杂的转移方程。假设我们有一个函数 f(i, j),表示从 i 个数字中选取余数为 j 的答案。对于任意的 L,我们需要计算:

[ f(i, j) = \sum_{x=0}^{p-1} f(L, x) \times f(i-L, (j + p - x) \bmod p) ]

这个方程的计算量较大,直接枚举前 L 个数字的余数并进行计算会非常耗时。为了优化计算,我们可以引入另一个函数 g(L, x),其定义为:

[ g(L, x) = \sum_{i=0}^{p-1} f(L, i) \times x^i ]

通过对动态规划转移方程进行变形,我们可以将 f(i, j) 表示为 g 函数的某种组合形式,这使得计算变得更加高效。

质数处理的关键思路

在处理质数时,我们可以利用欧拉筛法来标记质数。具体来说,我们创建一个布尔数组 vis,用于记录哪些数是质数。然后,我们通过筛法的方式标记所有合数,剩下的未标记的数即为质数。

这一步的关键在于,通过预处理将问题中的质数快速筛选出来,从而避免在后续计算中重复处理合数。这样可以显著减少计算量。

代码实现与优化

为了实现上述方法,我们可以编写如下的代码。代码主要包括以下几个部分:

  • 初始化:定义模数 mod 以及相关数组,用于存储动态规划函数 fFg 的值,以及快速幂相关的结果。
  • 筛法初始化:使用欧拉筛法标记质数,并记录质数的位置。同时,初始化动态规划函数的值。
  • 动态规划转移:通过对转移方程的变形,利用快速幂方法实现高效的计算。
  • 快速幂实现:编写快速幂函数,用于计算大指数幂的模运算结果。
  • 以下是具体的代码实现示例:

    #include 
    #include
    #include
    using namespace std;#define mod 20170408int n, m, p, vis[20000010], cnt, pre[2000000];long long f[210], F[210], g[210], G[210], c[210], x = 1;void work(long long *a, long long *b, long long *d) { int i, j; for (i = 0; i < p; ++i) { for (j = 0; j < p; ++j) { c[i + j] = (c[i + j] + a[i] * b[j]) % mod; } for (i = 0; i < p; ++i) { d[i] = (c[i] + c[i + p]) % mod; c[i] = 0; } }}int main() { int i, j; cin >> n >> m >> p; F[0] = G[0] = f[1] = g[1] = 1; for (i = 2; i <= m; ++i) { f[i % p]++; if (!vis[i]) { pre[++cnt] = i; vis[i] = false; } else { g[i % p]++; } for (j = 1; pre[j] * i <= m; ++j) { vis[pre[j] * i] = true; if (!(i % pre[j])) break; } } while (n) { if (n & 1) { work(F, f, F), work(G, g, G); } work(f, f, f), work(g, g, g); n >>= 1; } cout << (F[0] - G[0] + mod) % mod; return 0;}

    代码解释与优化

  • 模数定义mod 是一个常数,用于所有计算中的模运算,确保结果在合理范围内。
  • 初始化数组vis 数组用于记录质数,pre 数组用于欧拉筛法记录乘积数。
  • 筛法初始化:使用欧拉筛法标记质数,并初始化动态规划函数的值。
  • 动态规划转移:通过 work 函数实现动态规划转移方程的计算,利用快速幂优化计算效率。
  • 快速幂实现:通过递归或迭代快速幂方法实现高效计算,避免直接计算大指数。
  • 优化建议

    为了进一步优化代码,可以考虑以下方法:

  • 减少递归深度:对于快速幂部分,可以改用迭代实现,避免递归深度过大的问题。
  • 优化内存使用:尽量减少内存的使用,避免过多的数组分配。
  • 预计算常数:对于常用的常数值,可以提前预计算,减少计算时间。
  • 通过以上优化,可以使代码运行更加高效,适应更大的输入规模。

    转载地址:http://lovq.baihongyu.com/

    你可能感兴趣的文章
    OSPF太难了,这份OSPF综合实验请每位网络工程师查收,周末弯道超车!
    查看>>
    OSPF技术入门(第三十四课)
    查看>>
    OSPF技术连载10:OSPF 缺省路由
    查看>>
    OSPF技术连载11:OSPF 8种 LSA 类型,6000字总结!
    查看>>
    OSPF技术连载12:OSPF LSA泛洪——维护网络拓扑的关键
    查看>>
    OSPF技术连载13:OSPF Hello 间隔和 Dead 间隔
    查看>>
    OSPF技术连载14:OSPF路由器唯一标识符——Router ID
    查看>>
    OSPF技术连载15:OSPF 数据包的类型、格式和邻居发现的过程
    查看>>
    OSPF技术连载16:DR和BDR选举机制,一篇文章搞定!
    查看>>
    OSPF技术连载17:优化OSPF网络性能利器——被动接口!
    查看>>
    OSPF技术连载18:OSPF网络类型:非广播、广播、点对多点、点对多点非广播、点对点
    查看>>
    OSPF技术连载19:深入解析OSPF特殊区域
    查看>>
    SQL Server 复制 订阅与发布
    查看>>
    OSPF技术连载20:OSPF 十大LSA类型,太详细了!
    查看>>
    OSPF技术连载21:OSPF虚链路,现代网络逻辑连接的利器!
    查看>>
    OSPF技术连载22:OSPF 路径选择 O > O IA > N1 > E1 > N2 > E2
    查看>>
    OSPF技术连载2:OSPF工作原理、建立邻接关系、路由计算
    查看>>
    OSPF技术连载5:OSPF 基本配置,含思科、华为、Junifer三厂商配置
    查看>>
    OSPF技术连载6:OSPF 多区域,近7000字,非常详细!
    查看>>
    OSPF技术连载7:什么是OSPF带宽?OSPF带宽参考值多少?
    查看>>