Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3297 Accepted Submission(s): 1084 Problem Description On Mars, there is a huge company called ACM (A huge Company on Mars), and it’s owned by a younger boss. 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=354Author ZHANG, Chao Source 2011 Asia Dalian Regional Contest Recommend lcy | We have carefully selected several similar problems for you: 4056 4053 4057 4052 4054 |
题目大意:给出n个数,这n个数中求其互质的数的四次方的和
思路:首先我们求出1---n-1的所有的数的四次方的和,之后将n进行素因子分解,求出n的所有因子,然后减去包含这些因子的数的四次方就可以了。
- 四次求和公式,
- 逆元,四次求和公式中出现了除法,而除法取模不会保留形式,用费马小定理求得
- 容斥,求出与其不互质的四次方的和,最后直接减去即可
- 质因子分解
就基本完事了,注意,long long
那个四次求和公式:1^4 + 2^4 + ... + n^4 等价于=》 n(n+1)(2n+1)(3n^2+3n+1)/30 就是这里的除法!!!
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll fac[110];
ll n,inv,sum;
int factor(ll m) //质因子分解
{
sum=0;
ll tmp=m;
for(ll i=2;i*i<=tmp;i++)
if(tmp%i==0)
{
fac[sum++]=i;
while(tmp%i==0)
tmp/=i;
}
if(tmp>1) fac[sum++]=tmp;
return 0;
}
ll f(ll n) //四次求和公式,
{
ll ans=n;
ans=(ans*(n+1))%mod;
ans=(ans*(2*n+1))%mod;
ans=(ans*((3*n*n+3*n-1)%mod))%mod;
ans=(ans*inv)%mod;
return ans;
}
ll quick_pow(ll a,ll b,ll k) //快速幂
{
ll res=1;
while(b>0)
{
if(b%2)
res=(res*a)%k;
a=(a*a)%k;
b/=2;
}
return res;
}
ll work() //容斥定理直接求得最终结果,貌似dfs写更快一点....
{
ll ans=0,temp,flag;
for(int i=1; i<(1<<sum); i++)
{
temp=1;
flag=0;
for(int j=0; j<sum; j++)
if(i&(1<<j))
{
temp*=fac[j];
flag++;
}
ll t;
t=f(n/temp)%mod;
temp=(temp*temp)%mod;
temp=(temp*temp)%mod;
temp=(temp*t)%mod;
if(flag&1)
{
ans=(ans+temp)%mod;
}
else
{
ans=(ans-temp)%mod;
}
}
ll t=(f(n)-ans+mod)%mod;
printf("%lld\n",t);
}
int main()
{
inv=quick_pow(30,mod-2,mod);
int t;
cin>>t;
while(t--)
{
scanf("%lld",&n);
if(n==1)
{
cout<<0<<endl;
continue;
}
factor(n);
work();
}
return 0;
}