题目链接:This is the link
The Boss on MarsTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3290 Accepted Submission(s): 1082 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 |
题目大意:
给定 T 组数据,每组数据一个数 n ,然后让你求 <n且与 n 互素的数的四次方的和,结果对1000000007取模输出
思路:
就是求一个 S = a1^4 + a2^4 + ... + ak^4;,ai表示与n互素的数
直接枚举计算,要超时,所以要使用容斥定理计算,
需要推导四次方求和公式://尝试自己推一下
同时这里需要用逆元计算求模,所以需要计算30关于1000000007的逆元(233333335)
注意:还要自己写快速幂求模
//二进制求容斥定理
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include <iomanip>
#include<list>
#include<map>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define EPS 1e-8
//#define MOD 1e9+7
#define LL long long
#define ULL unsigned long long //1844674407370955161
#define INT_INF 0x7f7f7f7f //2139062143
#define LL_INF 0x7f7f7f7f7f7f7f7f //9187201950435737471
const int dr[]={0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]={-1, 1, 0, 0, -1, 1, -1, 1};
// ios::sync_with_stdio(false);
// 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之类的一起使用了。
vector<LL > fac;
const LL mod=1e9+7;
LL inv;//30关于mod的逆元
void Fac(LL n)//分解素因子
{
fac.clear();
for(LL i=2;i*i<=n;++i)
{
if(!(n%i))
{
fac.push_back(i);
while(!(n%i))
n/=i;
}
}
if(n>1)
fac.push_back(n);
}
LL Quick_pow(LL a,LL n)//快速幂求模
{
LL ret=1;
while(n)
{
if(n&1)
ret=ret*a%mod;
n>>=1;
a=a*a%mod;
}
return ret%mod;
}
LL Sum(LL n)//四次方求和
{
LL ret=n%mod;
ret=ret*(n+1)%mod;
ret=ret*(n+n+1)%mod;
ret=ret*((3*n*n+3*n-1)%mod)%mod;
ret=ret*inv%mod;
return ret;
}
void Solve(LL n)//容斥定理
{
Fac(n);
LL sum=fac.size();
LL ret=0;
for(int i=1;i<(1<<sum);++i)
{
LL ans=1;
LL cnt=0;
for(int j=0;j<sum;++j)
{
if(i&(1<<j))
{
ans=ans*fac[j]%mod;
++cnt;
}
}
if(cnt&1)
ret=(ret+Sum(n/ans)*Quick_pow(ans,4)+mod)%mod;
else
ret=(ret-Sum(n/ans)*Quick_pow(ans,4)+mod)%mod;
}
ret=(Sum(n)-ret+mod)%mod;
ret=(ret%mod+mod)%mod;
printf("%lld\n",ret);
}
int main()
{
inv=Quick_pow(30,mod-2);//计算30关于mod的逆元
int t;
scanf("%d",&t);
while(t--)
{
LL n;
scanf("%lld",&n);
Solve(n);
}
return 0;
}