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 }