The Boss on Mars
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2666 Accepted Submission(s): 846
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 them to get salaries from their boss. All employees are numbered from 1 to n. With the unknown reasons, if the employee’s work number is k, he can get k^4 Mars dollars this year. So the employees working for the ACM are very rich.
Because the number of employees is so large that the boss of ACM must distribute too much money, he wants to fire the people whose work number is co-prime with n next year. Now the boss wants to know how much he will save after the dismissal.
2 4 5
82 354HintCase1: sum=1+3*3*3*3=82 Case2: sum=1+2*2*2*2+3*3*3*3+4*4*4*4=354
题意:
求解(1~n)区间中与n互质的书的四次方和
题解:
转化为【1,n】的四次方和 - 不与n互质的数的四次方和
其中不与n互质的数
可以转化为求解n的质因子,然后利用容斥原理求解得到所有的与n不互质的数字
比如说30,质因子为 2 3 5
2 的倍数有 2 4 6 8 10.。。。30 提一个2得到 2*(1,2,3,4,5,,,,15)
3 的倍数有 3 6 9 。。。。 30
5的倍数有 5 10 15.。。。。30
2*3 的倍数 6 12 18.。。。。。30
2*5的倍数 10 20 30
3*5的倍数 15 30
2*3*5的倍数 30
然后对每一行的四次方和进行容斥原理求解
每一行可以转化为2 ^4* (1 ^4 + 2^4 +3^4 +.....+ 15^4)这样的形式
就可以求得答案了
注意:
本题求解的时候一定要注意防止溢出后再取模
传值的时候也全部需要传long long型的数据类型,最好把所有数据类型都定义成long long
四次方求和公式里面先取模再除以30,因此要求得30的模逆元,即:分子乘以30的模逆元
四次方求和公式:
(n+1)^5-n^5=5n^4+10n^3+10n^2+5n+1
n^5-(n-1)^5=5(n-1)^4+10(n-1)^3+10(n-1)^2+5(n-1)+1
……
2^5-1^5=5*1^4+10*1^3+10*1^2+5*1+1
全加起来
(n+1)^5-1^5=5*(1^4+2^4()+3^4+4^4+……+n^4)+10*(1^3+2^3+3^3+4^3+……+n^3)+10*(1^2+2^2+3^2+4^4+……+n^2)+5*(1+2+3+4+……+n)+n
因为1^3+2^3+3^3+4^3+……+n^3=[n(n+1)/2]^2
1^2+2^2+3^2+4^4+……+n^2=n(n+1)(2n+1)/6
1+2+3+4+……+n=n(n+1)/2
所以1^4+2^4+3^4+4^4+……+n^4
={[(n+1)^5-1^5]-10*[n(n+1)/2]^2-10*n(n+1)(2n+1)/6-5*n(n+1)/2-n}/5
=n(n+1)(2n+1)(3n^2+3n-1)/30
模逆元:
//------------模逆元--------------//
LL qpowMod(LL m,LL n,LL p)
{
LL ans=1;
LL temp=m;
while(n>0)
{
if(n&1)
ans=ans*temp%p;
temp=temp*temp%p;
n>>=1;
}
return ans;
}
LL getInverse(LL a,LL p)
{
return qpowMod(a,p-2,p);
}
//--------------------------------//
求解质因子:
//-----------求质因子-------------//
void devide(LL n)
{
tot=0;
for(LL i=2;i*i<=n;i++){
if(n%i==0){
a[tot++]=i;
while(n%i==0)
n=n/i;
}
}
if(n>1)//这里要记得
a[tot++]=n;
}
//--------------------------------//
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
const LL mod=1000000007;
int a[100],tot;
LL num;
//------------模逆元--------------//
LL qpowMod(LL m,LL n,LL p)
{
LL ans=1;
LL temp=m;
while(n>0)
{
if(n&1)
ans=ans*temp%p;
temp=temp*temp%p;
n>>=1;
}
return ans;
}
LL getInverse(LL a,LL p)
{
return qpowMod(a,p-2,p);
}
//--------------------------------//
//-----------求质因子-------------//
void devide(LL n)
{
tot=0;
for(LL i=2;i*i<=n;i++){
if(n%i==0){
a[tot++]=i;
while(n%i==0)
n=n/i;
}
}
if(n>1)//这里要记得
a[tot++]=n;
}
//--------------------------------//
LL calc(LL n)
{
LL ans=n;
ans=ans*(n+1)%mod;
ans=ans*(2*n+1)%mod;
ans=ans*((3*n*n%mod+3*n-1)%mod)%mod;
ans=(ans*num)%mod;
return ans;
}
//--------------------------------//
LL power(LL x)
{
return (((x*x)%mod*x)%mod*x)%mod;
}
//--------------------------------//
//----------容斥原理--------------//
LL deal(LL n)
{
LL ans=0;
for(LL i=1;i<(1LL<<tot);i++)
{
int sum=0,temp=1;
for(int j=0;j<tot;j++)
{
if(i&(1LL<<j)){
sum++;
temp=(temp*a[j])%mod;
}
}
if(sum&1)
ans=(ans%mod+(calc(n/temp)%mod*power(temp))%mod)%mod;
else
ans=(ans%mod-(calc(n/temp)%mod*power(temp))%mod+mod)%mod;
}
return ans;
}
//--------------------------------//
int main()
{
LL T,n;
num=getInverse(30,mod);//求逆元
//freopen("in.txt","r",stdin);
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
if(n==1){
puts("0");
continue;
}
devide(n);
LL t1=calc(n);
LL t2=deal(n);
printf("%lld\n",(t1-t2+mod)%mod);
}
return 0;
}
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
#define MAXN 1000000
const LL mod=1000000007;
int a[MAXN],tot;
LL num;
//------------模逆元--------------//
LL qpowMod(LL m,LL n,LL p)
{
LL ans=1;
LL temp=m;
while(n>0)
{
if(n&1)
ans=ans*temp%p;
temp=temp*temp%p;
n>>=1;
}
return ans;
}
LL getInverse(LL a,LL p)
{
return qpowMod(a,p-2,p);
}
//--------------------------------//
//-----------求质因子-------------//
void devide(LL n)
{
tot=0;
for(LL i=2;i*i<=n;i++){
if(n%i==0){
a[tot++]=i;
while(n%i==0)
n=n/i;
}
}
if(n>1)//这里要记得
a[tot++]=n;
}
//--------------------------------//
LL calc(LL n)
{
LL ans=n*(n+1)%mod;
ans=(ans*((2*n%mod+1)%mod))%mod;
LL temp=3*(n*n%mod);
temp=(temp%mod+3*n%mod-1)%mod;
ans=(ans*temp)%mod;
return ans*num%mod;
}
//--------------------------------//
LL power(LL x)
{
return (((x*x)%mod*x)%mod*x)%mod;
}
//--------------------------------//
//----------容斥原理--------------//
LL deal(LL n)
{
LL que[10000],pos=0,sum=0;
int q[10000];
q[pos]=1;
que[pos++]=-1;
for(LL i=0;i<tot;i++){
LL k=pos;
for(LL j=0;j<k;j++){
LL temp=power(q[j]*a[i]);
q[pos]=q[j]*a[i]%mod;
LL t;
if(que[j]>0)
t=temp%mod;
else
t=-temp%mod;
que[pos]=t*(-1)*calc(n/q[pos]);
if(que[pos]>0)
que[pos]=que[pos]%mod;
else
que[pos]=-((-que[pos])%mod);
pos++;
}
}
for(LL i=1;i<pos;i++)
sum=(sum+que[i])%mod;
return sum;
}
//--------------------------------//
int main()
{
LL T,n;
num=getInverse(30,mod);//求逆元
// freopen("in.txt","r",stdin);
scanf("%lld",&T);
while(T--)
{
scanf("%lld",&n);
if(n==0){
puts("0");
continue;
}
devide(n);
LL temp=calc(n);
LL t=deal(n);
printf("%lld\n",(temp-t+mod)%mod);
}
return 0;
}