Niu Ke Practice 58 E Max GCD

E Max GCD

Original title address:

https://ac.nowcoder.com/acm/contest/4090/E

20200228
Problem-solving idea: No matter what s and t, it is to find a k in the range of [l, r] so that the greatest common divisor of a [k] and x is the largest.
So we only need to store the divisor of each a [i] and its corresponding index (i), vec [divisor (a [i])] .push_back (i) , and then enumerate the divisors of x from large to small, right Each divisor of x is binary searched in the corresponding vec for whether there is an index in the range [l, r]. If it exists, then the corresponding divisor is the answer.

Reference Code:

#include <bits/stdc++.h>
using namespace std;
#define IO std::ios::sync_with_stdio(false)
#define ll long long
#define INF 0x3f3f3f3f

const int maxn = 1e5 + 10;
int n,q,a[maxn];
vector<int> vec[maxn];
void divisor(int x,int id){
    for(int i = 1 ; i * i <= x ; i++) {
        if (x % i == 0) {
            vec[i].push_back(id);
            if (x / i != i) vec[x / i].push_back(id);
        }
    }
}
int solve(int l,int r,int x){
    for(int i = 1 ; i * i <= x ; i++) if(x % i == 0){
        int j = x / i;
        int pos = lower_bound(vec[j].begin(),vec[j].end(),l) - vec[j].begin();
        if(pos < vec[j].size() && vec[j][pos] >= l && vec[j][pos] <= r) return j;
    }
    for(int i = sqrt(x) ; i >= 1 ; i--) if(x % i == 0){
        int j = i;
        int pos = lower_bound(vec[j].begin(),vec[j].end(),l) - vec[j].begin();
        if(pos < vec[j].size() && vec[j][pos] >= l && vec[j][pos] <= r) return j;
    }
}
signed main() {
    IO;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        divisor(a[i], i);
    }
    while (q-- > 0) {
        int l, r, x;
        cin >> l >> r >> x;
        cout << solve(l, r, x) << endl;
    }
    return 0;
}

Published 23 original articles · won 7 · visited 1747

Guess you like

Origin blog.csdn.net/weixin_44164153/article/details/104567139