题意:
就是在区间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含有四个参数。反正就是一道简单的数学题, 代码很简单。
代码:
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 }