题目链接: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=354
Author 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;elseret=(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;
}