题目概述

原题参考: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;
}

做题反思

幂次方时间复杂度真不高!!!

posted on 2024-03-02 00:36  山余木  阅读(31)  评论(0)    收藏  举报