【补题】牛客58E题(数学)

_X(KP0``4M1S]X(N3NRX2SS[5]

TNW1{S)5QZIF[J)GC4KP[30


题意:

      就是在区间l, r,中找gcd(ai, x)的最大值

首先,可以知道gcd(ai, x),必定是ai和x的约数,对吧。所以我们可以将每个ai的约数找出来,用vector<int> 的数组 value[i].push_back(id),表示aid有一个约数为i, 所以将id存入。然后对x同理求约数,将它的约数找在l,r区间相等且最大的数。输出这个数,就是答案。


反正我是被题整蒙了,就是下面这个东西,我以为gcd含有四个参数。反正就是一道简单的数学题, 代码很简单。

~(~$D)82Q1RYBK2KUBEF}[S


代码:


  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstring>
  4 using namespace std;
  5 
  6 constexpr size_t maxn = 1e5 + 5;
  7 vector<int> value[maxn];//存id 
  8 
  9 int solve(int l, int r, int x){
 10 	for(int i = 1; i * i <= x; ++ i){//先找最大的gcd值 
 11 		if(x % i == 0){
 12 			int j = x / i;
 13 			int k = lower_bound(value[j].begin(), value[j].end(), l) - value[j].begin();
 14 			if(k < value[j].size() && value[j][k] >= l && value[j][k] <= r)return j;
 15 		}
 16 	}
 17 	//若找不到,在找最小的 
 18 	for(int i = sqrt(x); i >= 1; -- i){
 19 		if(x % i == 0){
 20 			int k = lower_bound(value[i].begin(), value[i].end(), l) - value[i].begin();
 21 			if(k < value[i].size() && value[i][k] >= l && value[i][k] <= r)return i;
 22 		}
 23 	}
 24 }
 25 
 26 void push(int x, int id){//分解每个数的约数 
 27 	for(int i = 1; i * i <= x; ++ i){
 28 		if(x % i == 0){
 29 			value[i].push_back(id);
 30 			if(x / i != i)
 31 				value[x / i].push_back(id);//加入id 
 32 		}
 33 	}
 34 }
 35 
 36 int main(){
 37 	ios::sync_with_stdio(false);
 38 	cin.tie(0),cout.tie(0);
 39 	int n, m, a;
 40 	cin >> n >> m;
 41 	for(int i = 1; i <= n; ++ i){
 42 		cin >> a;
 43 		push(a, i);//分解约数 
 44 	}
 45 	while(m--){
 46 		int l, r, x;
 47 		cin >> l >> r >> x;
 48 		cout << solve(l, r, x) << endl;
 49 	}
 50 	return 0;
 51 }


追求吾之所爱
原文地址:https://www.cnblogs.com/rstz/p/12382227.html