题目概述
原题参考:C. Turtle Fingers: Count the Values of k
给出整数a,b,l,可以证明l=kaxby,问k最多有多少种选择
思路分析
这个题我是往往没想到暴力的,因为我觉得会比较大,但是事实上1e18才是2的五十多次,次方的时间复杂度真不高
我在做的时候实在想着容斥原理(苦笑),因为很容易看出来,当gcd(a, b)=1时,答案就是两者的一个排列,所以我在想当两者的gcd不为1时,是否可以通过容斥解决
参考代码
#include <bits/stdc++.h>
using namespace std;
#define FAST_IO ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define pll pair<long long, long long>
#define pii pair<int, int>
#define vi vector<int>
#define vl vector<long long>
#define ll long long
#define ull unsigned long long
const ll INF = 9187201950435737471;
const int inf = 2139062143;
const ll mod = 1e9 + 7;
const double eps = 1e-6;
const double PI = acos(-1.0);
int a, b, l, am, bm;
set<int> ans;
ll qpw(ll a, ll b, ll p) {
ll res = 1;
a %= p;
while(b) {
if(b&1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
void solve() {
ans.clear();
cin >> a >> b >> l;
if(a > b) swap(a, b);
for(int x=0; qpw(a, x, mod) <= l; x++) {
for(int y=0; qpw(b, y, mod) <= l; y++) {
if(l % qpw(a, x, mod) == 0 && l / qpw(a, x, mod) % qpw(b, y, mod) == 0) ans.insert(l / qpw(a, x, mod) / qpw(b, y, mod));
else break;
}
}
cout << ans.size() << endl;
}
int main() {
#ifdef xrl
freopen("in.txt", "r", stdin), freopen("out.txt", "w", stdout);
#endif
FAST_IO;
int t = 1;
cin >> t;
while(t --) solve();
#ifdef xrl
cout << "Time used = " << (double)(clock() * 1.0 / CLOCKS_PER_SEC) << "s";
#endif
return 0;
}
做题反思
幂次方时间复杂度真不高!!!
浙公网安备 33010602011771号