把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P2257 YY的GCD

题面传送门
首先我们可以列出这个式子:\(\sum\limits_{k\in pr}^{n}{\sum\limits_{i=1}^{n}{\sum\limits_{j=1}^{m}{[gcd(i,j)==k]}}}\)
如果你仔细阅读了莫比乌斯反演的相关内容,你大概可以推到\(\sum\limits_{k\in pr}^{n}{\sum\limits_{d=1}^{n}{\mu(d)\times \lfloor \frac{n}{kd}\rfloor\times \lfloor \frac{m}{kd}\rfloor}}\)
这个东西看上去很难优化。
我们可以设\(T=kd\)
然后我们就有\(\sum\limits_{k\in pr}^{n}{\sum\limits_{d=1}^{n}{\mu(d)\times \lfloor \frac{n}{T}\rfloor\times \lfloor \frac{m}{T}\rfloor}}\)
然后可以枚举\(T\)就有\(\sum\limits_{T=1}^{n}{\lfloor \frac{n}{T}\rfloor\times \lfloor \frac{m}{T}\rfloor\times \sum\limits_{k\in pr,k|T}{\mu(\lfloor\frac{T}{k}\rfloor)}}\)
然后后面那个在线性筛的时候顺便处理一下就好了。每次询问整除分块即可。
时间复杂度\(O(n+T \sqrt n)\)
code:

#include<cstdio>
#define ll long long
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int n,m,k,T,flag[10000039],w=1e7,pr[10000039],ph,mu[10000039],f[10000039],cnt;
inline void swap(ll &x,ll &y){x^=y^=x^=y;}
int main(){
	freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	register int i,j;register ll x,y,ans;
	scanf("%d",&T);mu[1]=1;
	for(i=2;i<=w;f[i]+=f[i-1],i++){
		(!flag[i])&&(pr[++ph]=i,mu[i]=-1,f[i]=1);
		for(j=1;j<=ph&&pr[j]*i<=w;j++){
			flag[pr[j]*i]=1;
			if(i%pr[j]==0){f[i*pr[j]]=mu[i];break;};
			mu[i*pr[j]]=-mu[i];f[i*pr[j]]=-f[i]+mu[i];
		}
	}
	while(T--){
		scanf("%lld%lld",&x,&y);(x>y)&&(swap(x,y),0);ans=0;
		for(i=1;i<=x;i=j+1)j=min(x/(x/i),y/(y/i)),ans+=(f[j]-f[i-1])*(x/i)*(y/i);printf("%lld\n",ans);
	}
}
posted @ 2021-03-11 20:20  275307894a  阅读(42)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end