zoukankan      html  css  js  c++  java
  • luoguP3455 [POI2007]ZAP-Queries

    题意

    (f(n)=sumlimits_{i=1}^{a}sumlimits_{j=1}^{b}[gcd(i,j)==n],F(n)=sumlimits_{n|d}f(d))

    发现(F(n)=frac{a}{n}*frac{b}{n}),可以理解为对(a)以内的所有(k*n)都和(b)以内的(k*n)配对了一次。

    由莫比乌斯反演:
    (f(n)=sumlimits_{n|d}mu(frac{d}{n})F(d))
    (f(n)=sumlimits_{n|d}mu(frac{d}{n})frac{a}{d}*frac{b}{d})
    (t=frac{d}{n})
    (f(n)=sumlimits_{t=1}^{min(frac{a}{d},frac{b}{d})}mu(t)frac{a}{t*n}frac{b}{t*n})

    (ans=f(d))

    除法分块即可。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=50010;
    int T;
    int mu[maxn],sum[maxn];
    ll a,b,d;
    bool vis[maxn];
    vector<int>prime;
    inline void shai(int n)
    {
    	vis[1]=1;mu[1]=1;
    	for(int i=2;i<=n;i++)
    	{
    		if(!vis[i])prime.push_back(i),mu[i]=-1;
    		for(unsigned int j=0;j<prime.size()&&i*prime[j]<=n;j++)
    		{
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+mu[i];
    }
    inline ll solve(ll a,ll b,ll d)
    {
    	ll n=min(a/d,b/d),res=0;
    	for(int l=1,r;l<=n;l=r+1)
    	{
    		r=min(a/(a/l),b/(b/l));
    		res+=(a/(l*d))*(b/(l*d))*(sum[r]-sum[l-1]);
    	}
    	return res;
    }
    int main()
    {
    	shai(50000);
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%lld",&a,&b,&d);
    		printf("%lld
    ",solve(a,b,d));
    	}
    	return 0;
    }
    
  • 相关阅读:
    slots属性(省内存,限制属性的定义)
    自定制格式化方式format
    改变对象的字符串显示__str__repr
    __getattribute__和item系列
    授权(类似)
    双下划线开头的attr方法
    动态导入模块
    反射
    python的单下划线和双下划线
    在子类中调用父类的方法
  • 原文地址:https://www.cnblogs.com/nofind/p/11939837.html
Copyright © 2011-2022 走看看