HAOI2011 部分题解

版权声明:https://blog.csdn.net/huashuimu2003 https://blog.csdn.net/huashuimu2003/article/details/85203866

p1518 Problem b

题目

https://www.luogu.org/problemnew/show/P2522

题解

莫比乌斯反演+容斥定理+整除分块。
参见 https://www.cnblogs.com/peng-ym/p/8647856.html

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=50010;
inline int read()
{
	int f=1,num=0;
	char ch=getchar();
	while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); }
	while (isdigit(ch)) num=(num<<1)+(num<<3)+(ch^48), ch=getchar();
	return num*f;
}
int num[maxn],vis[maxn],p[maxn],tot;
ll gcd(int a,int b,int k) 
{
    ll sum=0;
    if (a>b)	swap(a,b);
    a/=k,b/=k;
    for (int l=1,r;l<=a;l=r+1)
	{
        r=min(a/(a/l),b/(b/l));
        sum+=(ll)(num[r]-num[l-1])*(a/l)*(b/l);
    }
    return sum;
}
int main()
{
    num[1]=1;
    for (int i=2;i<=maxn;++i)
	{
        if (!vis[i])
			num[i]=-1,p[++tot]=i;
        for (int j=1;j<=tot&&(ll)i*p[j]<=maxn;++j)
		{
            vis[i*p[j]]=1;
            if(i%p[j]==0)	break;
            num[i*p[j]]=-num[i];
        }
        num[i]+=num[i-1];
    }
    int n=read();
    while (n--)
    {
    	int a=read(),b=read(),c=read(),d=read(),k=read();
    	ll ans=gcd(b,d,k)-gcd(b,c-1,k)-gcd(a-1,d,k)+gcd(a-1,c-1,k);
    	printf("%lld\n", ans);
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/huashuimu2003/article/details/85203866