zoukankan      html  css  js  c++  java
  • 【黑科技学习】光速幂

    昨天写了一道题,大概是这样的,给出一个三阶递推数列,求第(n)项的值。然后本蒟蒻大力推通项,搞出了(frac{(4n-13)*3^{n+2}+36+15*(-1)^n}{32})这个东西。

    题目有(T)组询问((1leq Tleq 5*10^7)),每次询问的(n)在long long范围内,且要求对(1e9+7)取模。当时没想那么多,直接一发快速幂提交了,然后大数据的点全T掉了。。。

    回过头去发现对于单个(n)的求值要求O(1)完成。思考一番,由于(p=1e9+7)是质数,所以由费马小定理得(a^{p-1}equiv 1(mod p)),然后求快速幂时传过去的指数可以变成(n) (mod) ((p-1))

    单次求解复杂度变成了原来的一半,还是会T。之后又考虑了各种卡常,没有用。然后就滚去参考(抄袭)题解了。

    发现唯一的不同就是高次幂的求法。(p)是在(2^{32})以内,如果我们以(2^{16}=65536)作为一个基准,那么所有的指数都可以表示为(n/65536*65536+n:mod: 65536)这种形式(这里/号是整除)。

    这有什么用呢?接下来指数(leq 65536)的数原样不变,指数(>65536)的写成((3^{65536})^{n/65536}*3^{n: mod: 65536})。开两个数组,一个表示(3^i),一个表示((3^{65536})^i)

    由于之前的等价处理,所以n变成了(1e9+7)以内的数,所以(frac{n}{65536}leq 65536),不会炸空间;而预处理两个数组之后单次求解的时间复杂度是O(1),写题解的神仙把它取名叫光速幂。

    注意:上文对n的变换只用于快速幂步骤,前面的(4n-13)还是要用原来的(n)去算的。

    题目链接:https://www.luogu.com.cn/problem/P5517

    代码就不贴了,相信大家都能自己写出来。

  • 相关阅读:
    java unicode转中文
    java常用
    Intellij IDEA常用快捷键——Mac版
    mac 快捷键
    thrift 学习
    ubuntu上的翻译软件,看论文神器
    linux中jupyter notebook中切换虚拟环境
    02_opencv_python_图像处理进阶
    01_opencv_python_基本图像处理
    python刷剑指offer(21-40)(一刷)
  • 原文地址:https://www.cnblogs.com/landmine-sweeper/p/13845445.html
Copyright © 2011-2022 走看看