E 最大GCD 思维+二分

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

思路:这道题有离线和在线做法。我们这里采用在线做法;

   首先需要初始化。

   我们针对每一个数,将其因数的vector都添加进这个数的下标,详情见代码中的init

   这样操作完毕之后,我们就能够将数组中的所有因数的组成部分的下标(由数组中的有这个因子的数的下标组成的)

   并且每一个因数所形成的数组都是从小到大排的(因为我们从第一个数枚举到最后一个,所以自然是从小到大)

   然后,接下来,我们找出所有询问的数的因数,对所有因素进行二分操作,然后取最大值即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=1e5+10;
 4 vector<int> Q[N];
 5 int a[N];
 6 void init(int n,int id){
 7     for(int i=1;i<=sqrt(n);i++){
 8         if(n % i == 0){
 9             Q[i].push_back(id);
10             if(n/i!=i) Q[n/i].push_back(id);
11         }
12     }
13 }
14 int solve(int x,int l,int r){
15     int p = lower_bound(Q[x].begin(),Q[x].end(),l) - Q[x].begin();
16     if(p == Q[x].size()) return 1;//不存在
17     if(Q[x][p]>=l&&Q[x][p]<=r) return x;
18     else return 1;
19 }
20 int main(){
21     int n,q;
22     cin>>n>>q;
23     for(int i=1;i<=n;i++){//预处理
24         cin>>a[i];
25         init(a[i],i);
26     }
27     int l,r,x;
28     for(int i=1;i<=q;i++){
29         cin>>l>>r>>x;
30         int ans = 0;
31         for(int j=1;j<=sqrt(x);j++){
32             if(x % j == 0){
33                 ans = max(ans,solve(j,l,r));
34                 if(x/j!=j) ans = max(ans,solve(x/j,l,r));
35             }
36         }
37         printf("%d\n",ans);
38     }
39 }
View Code

 

posted @ 2020-05-22 22:28  古比  阅读(137)  评论(0编辑  收藏  举报