bzoj 3309 DZY Loves Math —— 莫比乌斯反演+数论分块
Posted zinn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3309 DZY Loves Math —— 莫比乌斯反演+数论分块相关的知识,希望对你有一定的参考价值。
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3309
凭着上课所讲和与 Narh 讨论推出式子来;
竟然是第一次写数论分块!所以迷惑了半天;
在预处理的筛中也犯了愚蠢的错误...总之全仰仗 Narh 提点了...
所以具体题解就看这里咯:https://www.cnblogs.com/Narh/p/9740786.html
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=1e7+5; int T,a[xn],b[xn],c[xn],tot,pri[xn],cnt; ll s[xn]; bool vis[xn]; int rd() { int ret=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=0; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘)ret=(ret<<3)+(ret<<1)+ch-‘0‘,ch=getchar(); return f?ret:-ret; } void init() { int mx=1e7; for(int i=2;i<=mx;i++) { if(!vis[i])a[i]=b[i]=c[i]=1,pri[++cnt]=i; if(a[i]==1)s[i]=s[i-1]+((c[i]&1)?1:-1); else s[i]=s[i-1]; for(int j=1,k;j<=cnt&&(ll)i*pri[j]<=mx;j++) { vis[k=i*pri[j]]=1; if(i%pri[j])//新增pri[j] { if(!a[i]||(a[i]&&b[i]!=1))a[k]=0,b[k]=0; else a[k]=1,b[k]=1; c[k]=c[i]+1; } else { int w=k,t=0; while(w%pri[j]==0)w/=pri[j],t++; if(w==1||(a[w]&&b[w]==t))a[k]=1,b[k]=t; else a[k]=0,b[k]=0; c[k]=c[i]; } } } } int main() { T=rd(); init(); while(T--) { int n,m; n=rd(); m=rd(); ll ans=0; if(n>m)swap(n,m); for(int i=1,nxt;i<=n;i=nxt+1) ans+=(ll)(n/i)*(m/i)*(s[nxt=min(n/(n/i),m/(m/i))]-s[i-1]); printf("%lld ",ans); } return 0; }
以上是关于bzoj 3309 DZY Loves Math —— 莫比乌斯反演+数论分块的主要内容,如果未能解决你的问题,请参考以下文章