题意:求和 n<=100000
思路:很明显可以发现对于ans[n]=ans[n-1]+Σi<nlcm(i,n)。所以现在要解决的是Σi<nlcm(i,n)。
下面图片的思路很详细:
所以可以通过线性的方式先求出Σi<nlcm(i,n)。
#include <bits/stdc++.h> using namespace std; #define ll long long #define ull unsigned long long typedef unsigned int uint; const int N = 3000010; const int maxn=3e6+5; ll mod=1e9+7; int k=0; ull dp[N]; ull ans[N]; int phi[N]; ll qpow(ll base, int n) { ll a=base; ll res=1; while (n){ if (n&1) res=(res*a)%mod; a=(a*a)%mod; n>>=1; } return res; } void init() { memset(phi,0,sizeof(phi)); phi[1]=1; for(int i=2;i<maxn;i++) { if(!phi[i]) { for(int j=i;j<maxn;j+=i) { if(!phi[j]) { phi[j]=j; } phi[j]=phi[j]/i*(i - 1); } } } memset(dp,0,sizeof(dp)); dp[1]=1; memset(ans,0,sizeof(ans)); for(int i=2;i<maxn;i++) { for(int j=i;j<maxn;j+=i) { dp[j]+=((ull)phi[i])*i/2*j; } ans[i]=ans[i-1]+dp[i]; } } void solve(ll n,ll m) { } int main() { int t; int u=0; init(); scanf("%d",&t); while(t--){ ll n,m; scanf("%lld",&n); printf("Case %d: ",++u); printf("%llu ",ans[n]); } }