• 【洛谷P1072】Hankson 的趣味题


    题目大意:给定四个数字 a,b,c,d,求满足 (gcd(a,x)=b,lcm(c,x)=d) 的 x 的个数。

    题解:
    解法1:根据 lcm 的性质,x 一定为 d 的约数。因此,直接枚举 d 的约数,并判断是否满足上述条件即可,时间复杂度较高。
    解法2:解法一中直接枚举约数会导致有大量不满足条件的数字被枚举,导致复杂度的升高。仔细观察最大公约数和最小公倍数的性质可知,在算术基本定理中体现为质因子幂之间的联系。同时,x 的个数也可以转化成有多少种质因子分解使得上述条件成立。因此,在这里直接枚举 d 的每一个质因子,并利用算术基本定理之间的关系即可得知 x 的每一位的可能组成情况,最后利用乘法原理即可。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    
    int n,a,b,c,d;
    long long ans;
    vector<int> p;
    bool vis[maxn];
    
    void prework(){
    	vis[1]=1;
    	for(int i=2;i<=1e5;i++)if(!vis[i]){
    		p.push_back(i);
    		for(int j=i;j<=1e5/i;j++)vis[i*j]=1;
    	}
    }
    
    void solve(int pri){
    	int pa=0,pb=0,pc=0,pd=0;
    	while(a%pri==0)a/=pri,++pa;
    	while(b%pri==0)b/=pri,++pb;
    	while(c%pri==0)c/=pri,++pc;
    	while(d%pri==0)d/=pri,++pd;
    	if(pa==pb&&pd==pc)ans*=(pd-pb+1);
    	else if(pa>pb&&pd>pc&&pb==pd)ans*=1;
    	else if(pa>pb&&pd==pc)ans*=1;
    	else if(pa==pb&&pd>pc)ans*=1;
    	else ans=0;
    }
    
    void solve(){
    	scanf("%d",&n);
    	while(n--){
    		ans=1;
    		scanf("%d%d%d%d",&a,&b,&c,&d);
    		for(int i=0;i<p.size();i++)if(d%p[i]==0)solve(p[i]);
    		if(d!=1)solve(d);
    		printf("%lld
    ",ans);
    	}
    }
    
    int main(){
    	prework();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    c++ vs2019中编写nasm
    CF1242 A. Tile Painting题解(gcd)
    康托展开与逆康托展开
    CF 1459B Move and Turn 题解(思维)
    杨辉三角小性质
    CF 1028C Rectangles 题解(思维)
    Educational Codeforces Round 107 题解(A-E)
    HDU 5649 DZY Love Sorting 题解(二分套线段树)
    CF1336D Two Divisors 题解(gcd性质)
    题解 BZOJ1233 【[Usaco2009Open]干草堆tower】
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10543307.html
Copyright © 2020-2023  润新知