膜一下将带给你好运
发布时间: 2017年7月9日 18:17 最后更新: 2017年7月9日 21:05 时间限制: 1000ms 内存限制: 128M
描述
欧拉函数ϕ(n) 被定义1 ~n 中与n 互质的数的个数。例如ϕ(5)=4 ,因为1 ,2 ,3 ,4 这四个数字与5 互质。
定义f 函数:
f(n)=∑ i=233 n−233 ϕ(i)∗[n/i]
其中[n/i] 表示n 除以i 所得到的商
输入
第一行一个整数T ,表示测试组数。对于每组数据,输入一行,包含一个数字n ,466<=n<=10 8
输出
每组数据输出一行,表示函数值f(n) 对1000000007 取模
样例输入1
复制
2 1068 972
样例输出1
293824 222698
分析:有两种方法;
1.推公式,有Σ(i:1-n)Φ(n)*(n/i) = n*(n+1)/2,前后233可以欧拉公式暴力去除;
2.直接枚举n/i,不超过sqrt(n)个,求一下欧拉函数前缀和;
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <bitset> #include <map> #include <queue> #include <stack> #include <vector> #include <cassert> #include <ctime> #define rep(i,m,n) for(i=m;i<=(int)n;i++) #define mod 1000000007 #define inf 0x3f3f3f3f #define vi vector<int> #define pb push_back #define mp make_pair #define fi first #define se second #define ll long long #define pi acos(-1.0) #define pii pair<int,int> #define sys system("pause") #define ls rt<<1 #define rs rt<<1|1 const int maxn=1e6+10; const int N=5e2+10; using namespace std; ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);} ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;} int n,k,t; ll phi[maxn];//phi[n]表示x<=n,y<=n这样的互质(x,y)对; map<int,ll>dp; int m[maxn],p[maxn],pt; void init() { phi[1]=1; int N=maxn-9; int k; for(int i=2;i<N;i++) { if(!m[i]) p[pt++]=m[i]=i,phi[i]=i-1; for(int j=0;j<pt&&(k=p[j]*i)<N;j++) { m[k]=p[j]; if(m[i]==p[j]) { phi[k]=phi[i]*p[j]; break; } else phi[k]=phi[i]*(p[j]-1); } } for(int i=1;i<=maxn-10;i++)(phi[i]+=phi[i-1])%=mod; for(int i=1;i<=maxn-10;i++)phi[i]=(2*phi[i]%mod-1+mod)%mod; } ll dfs(int x) { if(x<=maxn-10)return phi[x]; else if(dp.count(x))return dp[x]; ll ret=1ll*x*x%mod; for(int i=2,j;i<=x;i++) { j=x/(x/i); ret-=dfs(x/i)*(j-i+1)%mod; (ret+=mod)%=mod; i=j; } return dp[x]=ret; } int main() { int i,j; init(); scanf("%d",&t); while(t--) { ll ret=0; scanf("%d",&n); for(i=233,j;i<=n-233;i++) { j=n/(n/i); j=min(j,n-233); (ret+=(dfs(j)-dfs(i-1)+mod)%mod*(n/i)%mod)%=mod; i=j; } printf("%lld\n",ret*qpow(2,mod-2)%mod); } return 0; }