于神之怒
2016-01-08 19:37
351 查看
题目大意
求∑ni=1∑mj=1gcd(i,j)kn,m,k<=5000000
繁衍
设h[i]=ik,显然h可以线筛出来。设n<=m如果不小于就调换。
设f[d]=∑ni=1∑mj=1(gcd(i,j)==d)
那么显然f[d]=∑⌊nd⌋i=1∑⌊md⌋j=1(gcd(i,j)==1)
这意味着我们进行分块,每一块的f值都相同。
ans=∑nd=1f[d]∗h[d]
容易想到求f使用莫比乌斯反演,于是
f[d]=∑⌊nd⌋i=1⌊nd∗i⌋∗⌊md∗i⌋∗μ[i]
那么同样进行分块,每一块的⌊nd∗i⌋∗⌊md∗i⌋一样。
所以线筛出h与μ即可。
参考程序
#include<cstdio> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; typedef long long ll; const ll mo=1000000007; ll mu[5000000+10],pri[1000000],h[5000000+10],sum[5000000+10],num[5000000+10]; bool bz[5000000+10]; ll i,j,k,l,r,t,n,m,nn,mm,p,top,tot,ans; ll quicksortmi(ll x,ll y){ if (!y) return 1; ll t=quicksortmi(x,y/2); t=t*t%mo; if (y%2) t=t*(x%mo)%mo; return t; } ll min(ll a,ll b){ if (a<b) return a;else return b; } int main(){ //freopen("D:/wa.txt","w",stdout); scanf("%lld%lld%lld",&n,&m,&p); if (n>m) swap(n,m); top=0; mu[1]=h[1]=1; fo(i,2,n){ if (!bz[i]){ pri[++top]=i; mu[i]=-1; h[i]=quicksortmi(i,p); } fo(j,1,top){ if (i*pri[j]>n) break; h[i*pri[j]]=1LL*h[i]*h[pri[j]]%mo; bz[i*pri[j]]=1; if (i%pri[j]==0) break; mu[i*pri[j]]=-mu[i]; } } sum[0]=num[0]=0; fo(i,1,n) num[i]=num[i-1]+mu[i],sum[i]=(sum[i-1]+h[i])%mo; i=1; while (i<=n){ j=min(n/(n/i),m/(m/i)); nn=n/i,mm=m/i; k=1;r=0; while (k<=nn){ l=min(nn/(nn/k),mm/(mm/k)); r=((nn/k)*(mm/k)%mo*(num[l]-num[k-1])%mo+r)%mo; k=l+1; } t=(sum[j]-sum[i-1])%mo; r=r*t%mo; ans=(ans+r)%mo; i=j+1; } printf("%lld\n",ans); }
相关文章推荐
- UITableViewCell的高亮和选中以及自绘分割线
- Gson 用户指南(中文)
- 20150108-小失误-中国流-执黑胜
- Android乐动力V5.75最新获Key方法,提交步数,QQ登陆获取key案例
- 答复学习汇编不顺利的准大学生
- [文章摘要]A semantic-enhanced trajectory visual analytics for digital forensic
- 你真的需要掌握多种语言吗?
- oracle跟踪事件(dump)总结
- ibatis.SqlMapClientTemplate的使用集锦
- oracle跟踪事件(dump)总结
- mysql 常用命令
- Python字符串操作
- java.lang.VerifyError: com/google/android/gms/measurement/internal/zzw
- java日期格式大全 format SimpleDateFormat
- alloc init初始化后对象依然还在父视图
- codevs 3269 混合背包
- 最少步数 OJ 58
- SpringMvc + Mybatis + Spring - 工程总结 ,基础知识结语篇
- Linux:如何获取Linux发行版的内核头文件
- 1010. 一元多项式求导 (25)