Niu Ke Practice 58 E Max GCD

E Max GCD

Endereço do título original:

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

20200228
Idéia de solução de problemas: não importa o que seja t, é encontrar um k no intervalo de [l, r] para que o maior divisor comum de a [k] e x seja o maior.
Portanto, precisamos armazenar apenas o divisor de cada a [i] e seu índice correspondente (i), vec [divisor (a [i])] .push_back (i) e depois enumerar os divisores de x de grande para pequeno, à direita Cada divisor de x é pesquisado em binário no vec correspondente para saber se existe um índice no intervalo [l, r]. Se existir, o divisor correspondente é a resposta.

Código de referência:

#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;
}

Publicado 23 artigos originais · ganhou 7 · visitou 1747

Acho que você gosta

Origin blog.csdn.net/weixin_44164153/article/details/104567139
Recomendado
Clasificación