秦九韶算法进行多项式求值:AcWing 871. 约数之和

(也称“秦氏算法”)是一种用于多项式求值的算法,由中国明代数学家秦九韶所创。该算法通过不断累乘和累加来减少求多项式值的运算次数,具有较高的效率和实用性。 假设要计算多项式 P(x) = a0 + a1x + a2x^2 + ... + an*x^n 在 x = k 处的值,可以使用传统的暴力方法直接计算,需要进行 (n+1)*n/2 次乘法和 n 次加法运算。使用秦九韶算法可以将计算次数降为 n次乘法和n次加法,从而提高计算效率。 具体来说,秦九韶算法的计算过程如下:

1. 初始化一个变量 sum = an。
2. 从 n-1 开始,依次执行以下操作:
·将 sum 乘以 x 的值。
·将得到的积加上 ai。
3. 得到最终结果 sum,即为多项式 P(x) 在 x = k 处的值。

以上引用自知乎:秦九韶算法 

#include
using namespace std;

const int N=110,mod=1e9+7;
typedef long long LL;

int main()
{
    int n;
    scanf("%d",&n);
    unordered_map primes;
    while(n--)
    {
        int x;
        scanf("%d",&x);
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                primes[i]++;
            }
        }
        if(x>1) primes[x]++;
    }
    LL res=1;
    for(auto prime:primes)
    {
        LL t=1;
        int a=prime.first,b=prime.second;
        for(int i=0;i

1.该题目要求的是所有的约数的和,我们需要知道,某一个固定的数字的约数是它的质因子的幂指数次方应该都属于该数字的约数,任意两个质因子之间的乘积也是属于该数字的约数,多个质因子,不固定的幂指数,它们的乘积都是属于该数字的约数。

2.根据上面的分析,我们要求所有的约数之和,其实就是求一个多项式的乘积,该多项式的形式是这样的

(p1^0+p1^1+p1^2+...+p1^a)*(p2^0+p2^1+p2^2+...+p2^b)* ...*(pk^0+pk^1+pk^2+...+pk^c),

p表示的是质因子,每一个括号里面罗列的是所有质因子的幂指数次方(在一定范围内的),把上面的多项式展开就是我们要求的答案

3.上面的多项式的计算,使用最上面介绍的秦九韶算法来进行实现,

    LL res=1;
    for(auto prime:primes)
    {
        LL t=1;
        int a=prime.first,b=prime.second;
        for(int i=0;i

a表示的是质因子(底数),b表示的是幂指数

4.把每一个输入的数字进行质因数分解,代码模板是这个

        int x;
        scanf("%d",&x);
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                primes[i]++;
            }
        }
        if(x>1) primes[x]++;

primes是一个哈希表,存储的是一种对应关系,核心的循环使用的是试除法

5.有一个需要注意的代码细节,我们使用秦九韶算法,每一次计算的是一个括号的内容,所以我们需要把res定义在循环外面,t定义在循环里面,(换句话说res只需要初始化一次,t需要初始化多次,这个多次取决于有多少个括号) 

6.以上就是这个题目的全部内容,没有比当傻瓜更简单的事儿了,为了一件事情疯狂,总有一天可以从中找到答案。

 

你可能感兴趣的:(算法竞赛,算法)