zoj3547

The Boss on Mars

Time Limit: 2 Seconds Memory Limit: 65536 KB

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 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.

Input

The first line contains an integer T indicating the number of test cases. (1 ≤ T ≤ 1000) Each test case, there is only one integer n, indicating the number of employees in ACM. (1 ≤ n ≤ 10^8)

Output

For each test case, output an integer indicating the money the boss can save. Because the answer is so large, please module the answer with 1,000,000,007.

Sample Input
2
4
5
Sample Output
82
354
Hint

Case1: sum=1+3*3*3*3=82
Case2: sum=1+2*2*2*2+3*3*3*3+4*4*4*4=354


题意:给出一个n,求n以内与n互质的数的四次方和

思路:首先得先知道1^4+2^4+……+n^4=(6*n^5+15*n^4+10*n^3+n)/30

这里主要涉及到求30的逆元,需要用扩展欧几里德乘以30的逆元,这里我用sum(n)来代替好了


然后是分析,要求n以内所有与其互质的数比较难,转而求不与其互质的数,即用上面的公式求得总的和,然后减去与其不互质数的四次方,接着找与其不互质的数又得用到容斥原理


比如12=2*2*3,可以知道12的质因数有2跟3,所以2的倍数与3的倍数与12都不互质,得出2 4 6 8 10 12 与3 6 9 12与12都不互质,但6跟12又重复出现了,因为它既是2的倍数又是3的倍数,因此得加上6的倍数,因此12的解法相当与(1^4+2^4+…12^4)-(2的所有倍数的四次方)-(3的所有倍数的四次方)+(6的所有倍数的四次方)


怎么得出这些数的所有倍数的四次方呢?假设要得出2的所有倍数的四次方,只需要求得sum(12/2),然后再用其乘上2的四次方,以上就是比较关键的几个地方

#include<stdio.h>
#include<string.h>
#define mod 1000000007
long long _30;
long long fac[1000],top;
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
    if(a==0&&b==0) return -1;
    if(b==0){x=1;y=0;return a;}
    long long d=extend_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
long long mod_reverse(long long a,long long n,long long b)
{
    long long x,y;
    long long d=extend_gcd(a,n,x,y);
   	long long tx,ty;
   	a/=d;
   	n/=d;
   	b/=d;
   	if(a<0) a=-a;
   	if(n<0) n=-n;
   	tx=(x*b%n+n)%n; 
   	return tx;
}
long long n4(long long x){
	return x%mod*x%mod*x%mod*x%mod;
}
long long pows(long long n,long long m){
	if(m==1)
		return n;
	if(m%2)
		return n*pows(n*n%mod,m/2)%mod;
	else return pows(n*n%mod,m/2);
}
long long sum(long long n){
	long long res=pows(n,5)*6%mod;
	res=(res+pows(n,4)*15)%mod;
	res=(res+pows(n,3)*10)%mod;
	res=((res-n)%mod+mod)%mod;
	res=res*_30%mod;
	return res;
}
void dfs(long long cur,long long now,int flag,long long n,long long &ans){
	if(cur>=top)
		return;
	long long temp=now*fac[cur];
	dfs(cur+1,now,flag,n,ans);
	if(flag)
		ans=(ans+sum(n/temp)*n4(temp)%mod)%mod;
	else ans=((ans-sum(n/temp)*n4(temp)%mod)%mod+mod)%mod;
	dfs(cur+1,temp,!flag,n,ans);
}

int main(void){
	_30=mod_reverse(30,mod,1);
	int t;
	long long n,temp;
	long long ans,res;
	scanf("%d",&t);
	while(t--){
		scanf("%lld",&n);
		temp=n;
		top=0;
		for(long long i=2;i*i<=temp;i++)
			if(temp%i==0){
				fac[top++]=i;
				while(temp%i==0)
					temp/=i;
			}
		if(temp!=1)
			fac[top++]=temp;
		ans=0;
		dfs(0,1,1,n,ans);
		res=sum(n);
		res=((res-ans)%mod+mod)%mod;
		printf("%lld\n",res);
	}
	
	
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值