[POI 2014]Solar Panels(数论)

题目链接

http://main.edu.pl/en/archive/oi/21/pan

题目大意

给定 a,b,c,d ,要找出点对 (i,j) , aib,cjd ,使得 gcd(i,j) 最大,求最大的这个 gcd(i,j)

思路

不妨考虑枚举 t=gcd(i,j) ,若在 aib,cjd 的限制下存在 gcd(i,j)=t ,当且仅当 [bt]>[at],[dt]>[ct]
但是直接暴力枚举 gcd(i,j) 还是太慢,可以发现 [bt],[at],[dt],[ct] 各自的不同的值都只有根号数量个。那我们可以对 t=gcd(i,j) 进行分块,每个块里的所有的 t 求出的 [bt],[at],[dt],[ct] 的值都是一样的,并用每个块里最后一个 t 更新答案即可。

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

using namespace std;

int main()
{
    int a,b,c,d,T;
    scanf("%d",&T);
    while(T--)
    {
        int ans=0;
        int last;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        for(int i=1;i<=b&&i<=d;i=last+1)
        {
            last=min(b/(b/i),d/(d/i));
            if(b/last>(a-1)/last&&d/last>(c-1)/last)
                ans=max(ans,last);
        }
        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:([POI 2014]Solar Panels(数论))