HDU4059 The Boss on Mars【容斥原理】【乘法逆元】【高次求和】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4059

题目大意:

给一个整数N,求1~N中与N互质的数的4次方的和。

解题思路:

题目简单,过程有点复杂。理清思路就简单了。

利用公式1^4 + 2^4 + … + n^4 = n*(n+1)*(2*n+1)*(3*n^2+3*n-1)/30,可以求出

1^4 + 2^4 + … + n^4,除以30可以先求出30模M的逆元,然后将上式中除以30改为

乘以30的逆元。

再来求与n不互质的数的4次方和。将n质因数分解为 n = p1^a1* p2^a2 * … * pn^an

(其中p1、p2为质数)。

这样不互质的数就是n的质因数的倍数,用容斥原理求出不互质的数的4次方和,最终

(1^4 + 2^4 + … + n^4 - 不互质的数的4次方和)即为所求,具体参考代码。

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL __int64
#define M 1000000007
using namespace std;

LL d,x,y,Inv,N;

void ExGcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        d = a;
    }
    else
    {
        ExGcd(b,a%b,d,y,x);
        y -= x*(a/b);
    }
}

LL ModInverse(LL a,LL n,LL &d,LL &x,LL &y)    //a*a-1 = 1(mod n) 用来计算30模M的逆元
{
    ExGcd(a,n,d,x,y);
    if(1 % d != 0)
        return -1;
    LL ans = x/d < 0 ? x/d + n : x/d;
    return ans;
}

LL Four(LL k)   //计算1^4 + 2^4 + … + k^4( 公式为 k*(k+1)*(2*k+1)*(3*k*k+3*k-1)/30 )
{
    LL ans = k;
    ans = ans * (k+1) % M;
    ans = ans * (2*k+1) % M;
    ans = ans * ((3*k*k%M+3*k-1)%M) % M;
    ans = (ans * Inv) % M;  // 除以30 等于 乘以30模M的逆元
    return ans;
//    return (k%M) * ((k+1)%M) % M * ((2*k+1)%M) % M * ((3*k*k%M + (3*k-1)%M)%M)%M * Inv;
}

LL Factor[20],ct;

void Divide()   //将N分解素因子
{
    ct = 0;
    LL n = N;
    for(LL i = 2; i <= sqrt(n*1.0); ++i)
    {
        if(n % i == 0)
        {
            Factor[ct++] = i;
            while(n % i == 0)
                n /= i;
        }
    }
    if(n != 1)
        Factor[ct++] = n;
}

LL Cal(LL a)
//计算 质因数乘积为a的所有小于n的倍数的前四次方和,
//即a^4 + (2a)^4 + (3a)^4 + … + (k*a)^4 = a^4 * (1^4 + 2^4 + … + k^4)
{
    LL k = N / a;
    LL ans = 1;
    for(int i = 1; i <= 4; ++i)
        ans = ans * a % M;
    ans = ans * Four(k) % M;
    return ans;
}

LL Solve()  //容斥原理求解与n不互质数的4次方和,最终结果为(1^4 + 2^4 + … + n^4 - 与n不互质数的4次方和)
{
    Divide();
    LL ans = 0;
    for(LL i = 1; i < (1 << ct); ++i)
    {
        LL odd = 0;
        LL tmp = 1;
        for(LL j = 0; j < ct; ++j)
        {
            if((1<<j) & i)
            {
                tmp *= Factor[j];
                odd++;
            }
        }
        if(odd & 1)
            ans = (ans%M + Cal(tmp)%M) % M;
        else
            ans = (ans%M - Cal(tmp)%M + M) % M;
    }
    return (Four(N) - ans + M)%M;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d",&N);
        if(N == 1)
            printf("0\n");
        else
        {
            Inv = ModInverse(30,M,d,x,y);   //求30模M的逆元
            printf("%I64d\n",Solve());
        }
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 20:25:35

HDU4059 The Boss on Mars【容斥原理】【乘法逆元】【高次求和】的相关文章

hdu4059---The Boss on Mars(容斥原理+前n项的4次方和)

Problem Description On Mars, there is a huge company called ACM (A huge Company on Mars), and it's owned by a younger boss. Due to no moons around Mars, the employees can only get the salaries per-year. There are n employees in ACM, and it's time for

hdu4059The Boss on Mars 容斥原理

//求1到n之间与n互质的数的四次方的和 //segma(n^4) = (6n^5+15n^4+10n^3-n)/30 //对于(a/b)%mod可以转化为(a*inv(b))%mod //inv(b)为b的逆元 //由费马小定理a^(p-1) = 1(modp) a , p 互质可得 //30的逆元为30^(mod-2) //由容斥原理很容易得到与n不互质的数之和为 //对于所有的n的素数因子 //一个素数因子的所有数的四次方之和-有两个素数因子的所有数的四次方之和+有三个.... //然后用

HDU 4059 The Boss on Mars ( 容斥原理)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4059 题意: 给定一个数n求小于n的与n互斥的数的四次方的和. 分析: 我们可以求出从1~n的所有数的四次方的和sum1,然后容斥求出1~n所有与n不互斥的数的四次方的和sum2: ans =sum1 - sum2; 设f(n)表示从1~n的所有数的四次方的和 f(n)=1/30*n*(n+1)(2n+1)(3n^2+3n-1); 推倒如下: (n+1)^5-n^5=5n^4+10n^3+10n^

hdu 4059 The Boss on Mars

The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1934    Accepted Submission(s): 580 Problem Description On Mars, there is a huge company called ACM (A huge Company on Mars), an

数论 + 容斥 - HDU 4059 The Boss on Mars

The Boss on Mars Problem's Link Mean: 给定一个整数n,求1~n中所有与n互质的数的四次方的和.(1<=n<=1e8) analyse: 看似简单,倘若自己手动推公式的话,还是需要一定的数学基础. 总的思路:先求出sum1=(1^4)+(2^4)+...(n^4),再求出sum2=(1~n中与n不互质的数的四次方的和),answer=sum1-sum2. 如何求sum1呢? 有两种方法: 1.数列差分.由于A={Sn}={a1^4+a2^4+...an^4}

The Boss on Mars

The Boss on Mars Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2327    Accepted Submission(s): 718 Problem Description On Mars, there is a huge company called ACM (A huge Company on Mars), and

HDU3037 Saving Beans(Lucas定理+乘法逆元)

题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个数是个经典问题,可以+1转化正整数解的个数用插板法解决:$C_{y+n-1}^{n-1}=C_{y+n-1}^y$. 而0<=y<=m,最后的结果就是—— $$\sum_{i=0}^m C_{i+n-1}^i$$ $$C_{n-1}^0+C_{n}^1+C_{n+1}^2+\dots+C_{n-1

UVa 11174 (乘法逆元) Stand in a Line

题意: 有n个人排队,要求每个人不能排在自己父亲的前面(如果有的话),求所有的排队方案数模1e9+7的值. 分析: <训练指南>上分析得挺清楚的,把公式贴一下吧: 设f(i)为以i为根节点的子树的排列方法,s(i)表示以i为根的子树的节点总数. f(i) = f(c1)f(c2)...f(ck)×(s(i)-1)!/(s(c1)!s(c2)!...s(ck)!) 按照书上最开始举的例子,其实这个式子也不难理解,就是先给这些子树确定一下位置,即有重元素的全排列. 子树的位置确定好以后,然后再确定

LightOJ - 1050 (唯一分解+推公式+乘法逆元)

题意:求a^b的所有约数和对1e9+7取模的结果 思路:对于一个数p,进行唯一分解,则p=P1^M1*P2^M2*...*Pn^Mn,则p的所有约数之和等于(P1^0+P1^1+...+P1^M1)*(P2^0+P2^1+...+P2^M2)*...*(Pn^0+Pn^1+...+Pn^Mn), p^t=P1^(M1*t)*P2^(M2*t)*...*Pn^(Mn*t),每一个(Pn^0+Pn^1+...+Pn^Mn)利用等比数列可以直接推出公式为(Pn^(Mn*t+1)-1)/(Pn-1),用