给你三个正整数 a 、 b 和 l ( a , b , l > 0 ) a 、 b 和 l ( a,b,l>0 ) a、b和l(a,b,l>0)。
可以证明,总有一种方法可以选择非负(即 ≥ 0 ) ≥0 ) ≥0)的整数 k 、 x k 、 x k、x 和 y y y ,使得 l = k ⋅ a x ⋅ b y l=k⋅a^x⋅b^y l=k⋅ax⋅by.
你的任务是找出所有这些方法中 k k k 的不同可能值的个数。
输入
第一行包含整数 t ( 1 ≤ t ≤ 1 0 4 ) t ( 1≤t≤10^4 ) t(1≤t≤104) - 测试用例的数量。
接下来的 t t t 行包含三个整数 a 、 b a 、 b a、b 和 l ( 2 ≤ a , b ≤ 100 、 1 ≤ l ≤ 1 0 6 ) l ( 2≤a,b≤100 、 1≤l≤10^6 ) l(2≤a,b≤100、1≤l≤106) —测试用例描述。 ( 2 ≤ a , b ≤ 100 , 1 ≤ l ≤ 1 0 6 ) ( 2≤a,b≤100 , 1≤l≤10^6 ) (2≤a,b≤100,1≤l≤106) —测试用例描述。
输出
输出 t t t 行,其中第 i ( 1 ≤ i ≤ t ) i ( 1≤i≤t ) i(1≤i≤t) 行包含一个整数,即第 i i i 个测试用例的答案。
Example
input
11
2 5 20
2 5 21
4 6 48
2 3 72
3 5 75
2 2 1024
3 7 83349
100 100 1000000
7 3 2
2 6 6
17 3 632043
output
6
1
5
12
6
11
24
4
1
3
24
注意此题给出了 5s 的时间限制,所以 O ( n 2 ) O(n^2) O(n2)是爆不了的,对于题目中的条件,需要我们找的是有多少种 k k k,但是注意此时给出了 a , b , l a,b,l a,b,l ,所以现在有三个未知量,故我们只需要枚举其中两个,就自然可以得到第三个未知量,如果你想枚举三个未知量再来进行判断不是闲的吗(说的就是我自己),而且容易TLE。
所以枚举 x x x 和 y y y ,因为已知 x x x 和 y y y 来解得 k k k 最为容易。
在枚举的时候需要回想起来题目条件是求多少种 k k k ,而不是多少种 x x x 和 y y y 的组合,所以要在过程中判重。
注意过程中 a a a 和 b b b 的各种次方相乘的时候会爆int
,所以在合适的地方开 long long
。
-
注意求k的时候我们运用的公式是: l a x ∗ b y \frac{l}{a^x*b^y} ax∗byl,首先k是正整数,所以不可能求出来k是个小数或分数,那么 a a a 和 b b b 最大就不能超过 l l l ,并且除出来应该是个整数,所以 l l l m o d mod mod a x ∗ b y a^x*b^y ax∗by 应该为 0 0 0。
-
接下来在判重的时候:由于 l l l 是固定的,所以只需要标记上所有出现过的 a x ∗ b y a^x*b^y ax∗by ,就可以做到对 k k k 的判重。
代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
const int N = 1e5 + 10;
#define ll long longint a[N];int main() {int t; cin >> t;while (t--) {map< ll, bool > vis; //map判重int a, b, l;cin >> a >> b >> l;long long res = 0; for (int aa = 1;aa <= l; aa *= a) {for (int bb = 1; bb <= l; bb *= b) {ll t = (ll)aa * bb;if (l % t == 0 && !vis[t]) {res++;vis[t] = 1; //标记重复}}}cout << res << endl;}return 0;
}