zoukankan      html  css  js  c++  java
  • POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]

    传送门:http://poj.org/problem?id=1845

    大致题意:

    求A^B的所有约数(即因子)之和,并对其取模 9901再输出。

    解题基础:

    1) 整数的唯一分解定理

    任意正整数都有且只有一种方式写出其素因子的乘积表达式。

    A= p_1^{k_1}*p_2^{k_2}*p_3^{k_3}...p_n^{k_n},其中p_i为素数

    2) 约数和公式

    对于已经分解的整数A= p_1^{k_1}*p_2^{k_2}*p_3^{k_3}...p_n^{k_n},A的所有因子之和为S=(1+p_1+p_1^{2}+p_1^{3}+...+p_1^{k_1})*(1+p_2+p_2^{2}+p_2^{3}+...+p_2^{k_2})*...*(1+p_n+p_n^{1}+p_n^{2}+p_n^{3}+...+p_n^{k_n})

    3) 同余模公式

    (a+b)%m=(a%m+b%m)%m

    (a*b)%m=(a%m*b%m)%m

    1: 对A进行素因子分解

    这里如果先进行筛50000内的素数会爆空间,只能用最朴素的方法进行分解

    2:A^B的所有约数之和为

    Sum=(1+p_1+p_1^{2}+p_1^{3}+...+p_1^{a_1*B})*(1+p_2+p_2^{2}+p_2^{3}+...+p_2^{k_2*B})*...*(1+p_n+p_n^{1}+p_n^{2}+p_n^{3}+...+p_n^{k_n*B})

    3: 求2中的等比序列

    由于给的数据量大,肯定不能直接用等比序列的求和公式,要用分治法进行求解

    S_n=1+q_1+q_2+q_3+...+q_n
ightarrowS_2n=(1+q_1+q_2+...q_n)+(1+q_1+q_2+...+q_n)*q_n=(1+q_1+q_2+..+q_n)*(1+q_n)=Sn*(1+q_n)

    一直对S_n递归求解

    S的下标为偶数类比一下

    4:反复平方法计算幂次式p^{n}

    一个快速幂取模的板子,直接套上

    #include<iostream>
    #include<string.h>
    #include<cstdio>
    using namespace std;
    int p[10000];
    int q[10000];
    const int mod = 9901;
    //快速幂取模板子
    long long qucick_pow(int m, int n, int moD)
    {
        if(n == 0)
            return 1;
        long long x = qucick_pow(m, n / 2, moD);
        long long ans = x * x % mod;
        if(n % 2)
            ans = ans * m % mod;
        return ans;
    }
    // 递归求解等比数列
    long long sum(int m, int n)
    {
        if(n == 0)
            return 1;
        if(n % 2)
        {
            return (sum(m, n / 2) * (1 + qucick_pow(m, n / 2 + 1, mod))) % mod;
        }
        else
        {
            return (sum(m, n / 2 - 1) * (1 + qucick_pow(m, n / 2 + 1, mod)) + qucick_pow(m, n / 2, mod)) % mod;
        }
    }
    int main()
    {
        int a, b;
        scanf("%d %d", &a, &b); 
        int cnt = 0;
        for(int i=2;i*i<=a;)
        {
            if(a%i==0)
            {
                p[cnt]=i;
                while(a%i==0)
                {
                    a/=i;
                    q[cnt]++;
                }
                cnt++;
            }
            if(i==2)
                i+=1;
            else
                i+=2;
        }
        if(a!=1)
            p[cnt]=a,q[cnt++]=1;
        long long ans = 1;
        for(int i = 0; i < cnt; i++)
        {
            ans = (ans * (sum(p[i], q[i] * b) % mod)) % mod;
        }
        cout << ans % mod << endl;
    }
  • 相关阅读:
    Jboss部署war以及获取Resource的真实路径
    命令行获取docker远程仓库镜像列表
    Hibernate5 与 Spring Boot2 最佳性能实践
    Spring Bean的一生
    Spring中统一相同版本的api请求路径的一些思考
    Java并发工具类CountDownLatch源码中的例子
    (转载)23种设计模式的uml图表示及通俗介绍
    GeoHash核心原理解析
    如何保证服务器的安全?
    小强升职记
  • 原文地址:https://www.cnblogs.com/yyaoling/p/12260431.html
Copyright © 2011-2022 走看看