cf Educational Codeforces Round 106 D. The Number of Pairs

2024-03-24 07:32

本文主要是介绍cf Educational Codeforces Round 106 D. The Number of Pairs,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题:
D. The Number of Pairs
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

You are given three positive (greater than zero) integers c, d and x.

You have to find the number of pairs of positive integers (a,b) such that equality c⋅lcm(a,b)−d⋅gcd(a,b)=x holds. Where lcm(a,b) is the least common multiple of a and b and gcd(a,b) is the greatest common divisor of a and b

.
Input

The first line contains one integer t (1≤t≤10^4) — the number of test cases.

Each test case consists of one line containing three integer c, d and x (1≤c,d,x≤10^7).
Output

For each test case, print one integer — the number of pairs (a,b) such that the above equality holds.
Example
Input
Copy

4
1 1 3
4 2 6
3 3 7
2 7 25

Output
Copy

4
3
0
8

Note

In the first example, the correct pairs are: (1,4), (4,1), (3,6), (6,3).

In the second example, the correct pairs are: (1,2), (2,1), (3,3).

中文:

给你c,d,x三个数,让你找出满足下面
c⋅lcm(a,b)−d⋅gcd(a,b)=x 这个方程的所有(a,b)的对数。

代码:

    #include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e7 + 3;int t,c,d,x;vector<int> f;int pow2[35];int prim_factor[maxn];int tmp[maxn];int gcd(int a,int b){if(a%b==0)return b;return gcd(b,a%b);}void get_factor(vector<int>& v, int k){for (int i=1; i * i <= k; i++){if (k % i == 0){v.push_back(i);if ( k != i * i){v.push_back(k/i);}}}//v.push_back(k);}int cnt_prim_factor(int k){int cnt = 0;int i = 2;while(k != 1){if (k % i == 0){cnt++;while(k%i == 0){k=k/i;}}i++;}return cnt;}int main(){ios::sync_with_stdio(false);memset(tmp, -1, sizeof(tmp));memset(prim_factor, 0, sizeof(prim_factor));tmp[1]=1;for (int i=2;i<maxn;i++){if (tmp[i] == -1){for (int j=i;j<maxn;j+=i){if (tmp[j] == -1){tmp[j] = i;}}}}for (int i=2;i<maxn;i++){int j = i / tmp[i];prim_factor[i] = prim_factor[j] + (tmp[i] != tmp[j]);}pow2[0] = 1;for (int i=1;i<=30;i++){pow2[i] = pow2[i-1] * 2;}cin>>t;while(t--){cin>>c>>d>>x;int fac = gcd(c,d);fac = gcd(fac, x);c/=fac;d/=fac;x/=fac;f.clear();get_factor(f, x);int ans = 0;for (int i=0;i<f.size();i++){int ab = x / f[i] + d;//cout<<"ab = " << ab <<" f = " <<f[i] << " d = " <<d<<endl;if (ab % c ==0){ab= ab / c;int tmp = prim_factor[ab];ans += pow2[tmp];}}cout<<ans<<endl;}return 0;}

解答:

首先要想到(a,b)这两个数的gcd和lcm的关系,a × b / gcd(a,b) = lcm(a,b),如果a × b / gcd(a,b) / gcd(a,b),那么可以表示成
a×b = p1 × p2 × gcd(a,b) × gcd(a,b),其中p1和p2是两个互质的数。按照这个原则,把下面的方程变换一下,即左右除以gcd(a,b),有:

c⋅lcm(a,b)−d⋅gcd(a,b)=x
变成
c × p1 × p2 - d = x / gcd(a,b)
再变换一下
p1×p2 = (x / gcd(a,b) + d) / c
可以看出,就是找等号后面表达式是否成利,并且中有多少个互质的p1和p2
其中要求x / gcd(a,b)能除开,那么就要求gcd(a,b)必须是x的因子。
现在枚举x的因子,那么可以得到等号右边的表达式,设(x / gcd(a,b) + d) / c = k
根据唯一分解定理,可以将k分解成 q 1 n 1 q 2 n 2 q 3 n 3 . . . . q x n y q_1^{n1}q_2^{n2}q_3^{n3}....q_x^{n_y} q1n1q2n2q3n3....qxny,要想p1和p2两个数互质,那只要保证从分解出来的这些 q 1 q_1 q1 q x q_x qx这x个数分成两堆,一堆组成p1,剩下的一堆组成p2即可,取数的方法是 C x 0 + C x 1 + . . . + C x x = 2 x C_{x}^{0} + C_{x}^{1} +...+C_{x}^{x} = 2^x Cx0+Cx1+...+Cxx=2x
把所有枚举的因子都计算一次上面的分解计数并累加,最后就是答案

这题有个坑点,需要打出每个数的素因子的个数表,按照程序中的打表方法不会超时。

这篇关于cf Educational Codeforces Round 106 D. The Number of Pairs的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/840874

相关文章

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

cf 164 C 费用流

给你n个任务,k个机器,n个任务的起始时间,持续时间,完成任务的获利 每个机器可以完成任何一项任务,但是同一时刻只能完成一项任务,一旦某台机器在完成某项任务时,直到任务结束,这台机器都不能去做其他任务 最后问你当获利最大时,应该安排那些机器工作,即输出方案 具体建图方法: 新建源汇S T‘ 对任务按照起始时间s按升序排序 拆点: u 向 u'连一条边 容量为 1 费用为 -c,

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

CF 508C

点击打开链接 import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String [] args){new Solve().run() ;} }class Solve{int bit[] = new int[608] ;int l

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja