參考:http://blog.csdn.net/wzf_2000/article/details/54630931
有這樣一個顯然的結論:當\( |\mu(n)|==1 \)時,\( \phi(nk)=\phi(k)\sum_{d|gcd(n,k)}\phi(\frac{n}ze8trgl8bvbq) \)然后看n的范圍比較友好就先不去管它,先看后面的:
\[ if |\mu(i)|==1 \]
\[ \sum_{k=1}^{i}\sum_{d|i,d|k}\phi(\frac{n}ze8trgl8bvbq)\phi(k) \]
\[ =\sum_{d|i}\phi(\frac{n}ze8trgl8bvbq)\sum_{k=1}^{\left \lfloor \frac{m}ze8trgl8bvbq \right \rfloor}\phi(dk) \]
發現這形成了一個子問題的形式,于是可以用杜教篩。
對于其他的部分,k是i的因數中最大的且\( |\mu(k)|==1 \)的數:
\[ if |\mu(i)|==0 \]
\[ \sum_{j=1}^{m}\phi(ij)=\frac{i\sum_{j=1}^{m}\phi(kj)}{k} \]
時間復雜度不會算
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
const int N=1000005,m=1000000,mod=1e9+7;
int phi[N],mi[N],q[N],tot,n,k,s[N],ans[N];
bool v[N];
map<long long,int>mp;
int S(int n,int l)
{if(l<=1)return phi[n*l];if(n==1){if(l<=m)return s[l];if(ans[k/l]!=-1)return ans[k/l];long long re=(long long)l*(l+1)/2%mod;for(int i=2,la;i<=l;i=la+1){la=l/(l/i);if(l/i<=m)re=(re-(long long)s[l/i]*(la-i+1)%mod)%mod;elsere=(re-(long long)S(1,l/i)*(la-i+1)%mod)%mod;}return ans[k/l]=(re%mod+mod)%mod;}if(mp[(long long)n*mod+l])return mp[(long long)n*mod+l];long long re=0ll;for(int i=1;i*i<=n;i++)if(n%i==0){re=(re+(long long)phi[n/i]*S(i,l/i)%mod)%mod;if(i*i!=n)re=re+(long long)phi[i]*S(n/i,l/(n/i))%mod;}return mp[(long long)n*mod+l]=(re%mod+mod)%mod;
}
int main()
{memset(ans,-1,sizeof(ans));mi[1]=phi[1]=1;for(int i=2;i<=m;i++){if(!v[i]){q[++tot]=i;phi[i]=i-1;mi[i]=i;}for(int j=1;j<=tot&&i*q[j]<=m;j++){int k=i*q[j];v[k]=1;if(i%q[j]==0){phi[k]=phi[i]*q[j];mi[k]=mi[i];break;}phi[k]=phi[i]*(q[j]-1);mi[k]=mi[i]*q[j];}}for(int i=1;i<=m;i++)s[i]=(s[i-1]+phi[i])%mod;scanf("%lld%lld",&n,&k);if(n>k)swap(n,k);long long ans=0ll;for(int i=1;i<=n;i++)ans=(ans+((long long)i/mi[i]*S(mi[i],k)%mod))%mod;printf("%lld\n",(ans%mod+mod)%mod);return 0;
}
轉載于:https://www.cnblogs.com/lokiii/p/8330148.html
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的bzoj 3512: DZY Loves Math IV【欧拉函数+莫比乌斯函数+杜教筛】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。