loj6229 这是一道简单的数学题
题解:https://blog.csdn.net/Vectorxj/article/details/79094659
套路推式子,杜教筛,证明复杂度。
感谢NicoDafaGood,不在这里写题解了,式子列出来太长啦,写在本本上。
//Serene #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<map> using namespace std; #define ll long long #define db double #define For(i,a,b) for(int i=(a);i<=(b);++i) #define Rep(i,a,b) for(int i=(a);i>=(b);--i) const ll mod=1e9+7; const int maxn=2e6+7,W=2e6; ll n,g[maxn],inv6; char cc;ll ff; template<typename T>void read(T& aa) { aa=0;cc=getchar();ff=1; while((cc<'0'||cc>'9')&&cc!='-') cc=getchar(); if(cc=='-') ff=-1,cc=getchar(); while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar(); aa*=ff; } ll pf(ll x) {return x*x%mod;} ll qp(ll x,ll k) { ll rs=1; while(k) { if(k&1) rs=rs*x%mod; k>>=1; x=x*x%mod; } return rs; } ll mu[maxn],prime[maxn],totp; bool ok[maxn]; void get_p() { mu[1]=1; For(i,2,W) { if(!ok[i]) { prime[++totp]=i; mu[i]=-1; } For(j,1,totp) { if(prime[j]>W/i) break; ok[i*prime[j]]=1; if(i%prime[j]) mu[i*prime[j]]=-mu[i]; else { mu[i*prime[j]]=0; break; } } } For(i,1,W) g[i]=((g[i-1]+mu[i]*pf(i))%mod+mod)%mod; } inline ll f2(ll x) {return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;} map<ll,ll> G,H; ll get_g(ll n) { if(n<=W) return g[n]; ll p=G[n]; if(p) return p; ll rs=0,lst=1,now; for(ll i=2,j;i<=n;i=j+1) { j=n/(n/i); now=f2(j); rs+=get_g(n/i)*(now-lst+mod)%mod; lst=now; } rs=(1-rs%mod+mod)%mod; return G[n]=rs; } inline ll get_h(ll n) { if(H[n]) return H[n]; ll rs=0,lst=0,now; for(ll i=1,j;i<=n;i=j+1) { j=n/(n/i); now=get_g(j); rs+=(n/i)*(now-lst+mod)%mod; lst=now; } return H[n]=rs%mod; } ll get_f(ll n) { ll rs=0,x; for(ll i=1,j;i<=n;i=j+1) { j=n/(n/i); x=n/i; rs+=pf(((x+1)*x/2)%mod)*(get_h(j)-get_h(i-1)+mod)%mod; } return rs%mod; } int main() { read(n); get_p(); inv6=qp(6,mod-2); ll x=get_f(n); printf("%lld\n",(x+n)*qp(2,mod-2)%mod); return 0; }
弱者就是会被欺负呀