zoukankan      html  css  js  c++  java
  • [HAOI2011]Problem b

    洛谷题目链接

    简单的数论题

    我们需要求:$$sumlimits_{i=a}^b sumlimits_{j=c}^d [gcd(i,j)=k]$$

    我们发现可以像二维前缀和一样容斥,所以我们只要会求下面的式子,上面的式子也就能解啦:$$sumlimits_{i=1}^n sumlimits_{j=1}^m [gcd(i,j)=k]$$

    下面默认(n<m)

    那么按照套路来吧:$$sumlimits_{i=1}^{leftlfloor frac{n}{k} ight floor} sumlimits_{j=1}^{leftlfloor frac{m}{k} ight floor} [gcd(i,j)=1]$$

    莫比乌斯反演:$$sumlimits_{i=1}^{leftlfloor frac{n}{k} ight floor} sumlimits_{j=1}^{leftlfloor frac{m}{k} ight floor} sumlimits_{d|gcd(i,j)} mu (d)$$

    枚举(d):$$ sumlimits_{d=1}^{leftlfloor frac{n}{k} ight floor} mu (d) sumlimits_{i=1}^{leftlfloor frac{n}{k} ight floor} sumlimits_{j=1}^{leftlfloor frac{m}{k} ight floor} [d|gcd(i,j)]$$

    除以(d):$$sumlimits_{d=1}^{leftlfloor frac{n}{k} ight floor} mu (d) sumlimits_{i=1}^{leftlfloor frac{n}{kd} ight floor} sumlimits_{j=1}^{leftlfloor frac{m}{kd} ight floor} 1$$

    发现后面可以用整除分块做:$$sumlimits_{d=1}^{leftlfloor frac{n}{k} ight floor} mu (d) leftlfloor frac{n}{kd} ight floor leftlfloor frac{m}{kd} ight floor$$

    这样我们就可以欢乐整除分块啦~~~

    接下来是美滋滋的代码时间~~~

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 50007
    using namespace std;
    int T;
    int a,b,c,d,k,cnt;
    int mu[N],num[N],prime[N];
    bool isp[N];
    void Get_mu()
    {
    	mu[1]=1;
    	for(int i=2;i<=N-7;++i)
    	{
    		if(!isp[i])
    		{
    			prime[++cnt]=i;
    			mu[i]=-1;
    		}
    		for(int j=1;j<=cnt&&(i*prime[j])<=N-7;++j)
    		{
    			isp[i*prime[j]]=1;
    			if(i%prime[j]==0)
    				break;
    			else
    				mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<=N-7;++i)
    		num[i]=num[i-1]+mu[i];
    }
    int Get(int n,int m,int k)
    {
    	if(n>m)
    		swap(n,m);
    	int nn=n/k;
    	int ans=0;
    	for(int l=1,r;l<=nn;l=r+1)
    	{
    		r=min((n/k)/(n/l/k),(m/k)/(m/l/k));
    		ans+=(num[r]-num[l-1])*(n/l/k)*(m/l/k);
    	}
    	return ans;
    }
    int main()
    {
    	Get_mu();
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
    		printf("%d
    ",Get(b,d,k)-Get(a-1,d,k)-Get(c-1,b,k)+Get(a-1,c-1,k));
    	}
    	return 0;
    }
    
  • 相关阅读:
    洛谷 P1194 飞扬的小鸟 题解
    洛谷 P1197 星球大战 题解
    洛谷 P1879 玉米田Corn Fields 题解
    洛谷 P2796 Facer的程序 题解
    洛谷 P2398 GCD SUM 题解
    洛谷 P2051 中国象棋 题解
    洛谷 P1472 奶牛家谱 Cow Pedigrees 题解
    洛谷 P1004 方格取数 题解
    洛谷 P2331 最大子矩阵 题解
    洛谷 P1073 最优贸易 题解
  • 原文地址:https://www.cnblogs.com/yexinqwq/p/11171944.html
Copyright © 2011-2022 走看看