牛客练习赛58 E-最大GCD(gcd)

传送门

题意:

在这里插入图片描述

思路:

要想让 [ l , r ] [l,r] ,选出来个区间的 g c d gcd 值最大,最优是,只有在 [ l , r ] [l,r] 区间找一个值使得 g c d ( x , a [ i ] ) gcd(x,a[i]) 最大即可, x x 一定是 a [ i ] a[i] 的因子
因此我们先处理每一个 a [ i ] a[i] ,用一个 v e c t o r vector ,把 a [ i ] a[i] 的所有因子里都放入 i i ,意思就是该因子在i位置可以得到
然后对于每次询问,我们遍历 x x 的每一个因子 k k ,如果该因子能够在 l , r l,r 范围内找到,与结果相比取最大值即可
查询一个数在能不能在 l , r l,r 范围内找到用二分
lower_bound( )lower_bound( )的用法

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
#include <stack>
typedef long long ll;
#define PII make_pair
#define pb push_back
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int MAXN=1e5+50;
const int inf=0x3f3f3f3f;
const int M=5000*4;
vector<int>p[MAXN];
bool check(int x,int l,int r){
	int len=p[x].size();
	if(len==0||p[x][0]>r||p[x][len-1]<l)return 0;
	int pos=lower_bound(p[x].begin(),p[x].end(),l)-p[x].begin();
	if(p[x][pos]<=r) return 1;
	else return 0;
}
int main()
{   
    int n,q,x;
    scanf("%d%d",&n,&q);
    rep(i,1,n){
    	scanf("%d",&x);
    	for(int j=1;j*j<=x;j++){
    		if(x%j==0){
    			p[j].pb(i);
    			if(j!=x/j)p[x/j].pb(i);
    		}
    	}
    }
    int l,r;
    while(q--){
    	int ans=0;
    	scanf("%d%d%d",&l,&r,&x);
    	for(int i=1;i*i<=x;i++){
    		if(x%i==0){
    			if(check(i,l,r))
    				ans=max(ans,i);
    			if(check(x/i,l,r))
    				ans=max(ans,x/i);
    		}
    	}
    	printf("%d\n",ans);
     }
    return 0;
} 

另一种写法,用了两次二分,只过了91%的样例,有点超时

int l,r;
    while(q--){
        int ans=0;
        scanf("%d%d%d",&l,&r,&x);
        for(int i=1;i*i<=x;i++){
            if(x%i==0){
                if(lower_bound(p[i].begin(),p[i].end(),l)!=upper_bound(p[i].begin(),p[i].end(),r))
                    ans=max(ans,i);
                if(lower_bound(p[x/i].begin(),p[x/i].end(),l)!=upper_bound(p[x/i].begin(),p[x/i].end(),r))
                    ans=max(ans,x/i);
            }
        }
        printf("%d\n",ans);
     }
发布了142 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44091178/article/details/104575344