upc 曾经排队 数学

曾经排队
时间限制: 1 Sec 内存限制: 128 MB

题目描述
他还记得出发前,头马壮烈的嘶鸣,以及众马沸腾的银河一般的呐喊。
他远远的,视线绕过头马,看向远方。
他记得自己什么光也没看到。
出发前,群马要列队。
为了奔跑时方便管理,头马把这些马分成了n组,第i组有ci匹马。
为了使队形更整齐,美观,他制定了一个必须满足的规定:
每一组都要排成几行。有一个统一给定的正整数a,每一行的马匹数都不能超过a,而且每一组中只能有最多一行马的数量不足a匹。
他还提出了如下两个要求:
1.每一行的马匹数都正好a匹。
2.对于任意一组,每行马匹数都必须严格小于行数(不可以等于)。
现在,头马想询问如果每一行有匹马,是否能满足第1/2个要求。
由于他想确定最好看的方案,所以他会有q次询问。
输入
第一行一个正整数n,表示组数。
第二行n个正整数,第i个正整数ci,表示第i组的马匹数。
第三行一个正整数q,表示询问数。
接下来q行,每行两个正整数a‬b,表示每一行a匹马是否满足第b个规定(b=1或2)。
输出
共q行,第i行一个字符Yes或No(不输出引号),表示第i个询问能否被满足。
样例输入 Copy
4
16 18 12 24
4
4 1
2 1
4 2
3 2
样例输出 Copy
No
Yes
No
Yes
提示
样例解释
第一个询问,如果每行4匹马,第二个方阵每行的马匹数就不可能相等,因此不满足第一个条件,输出No
第二个询问,第一组可以排成8行,第二组可以排成9行,第三组可以排成6行,第四组可以排成12行,输出Yes
第三个询问,第三组每行马匹数(即给定的4匹)多于行数,输出No
第四个询问,每一组每行马匹数都严格小于行数,输出Yes

对于所有数据,1≤n,q≤7×105,1≤ci,a≤1018,1≤b≤2

这个数据出的好啊。。直接把我这个不想动脑子直接写二分的给卡掉了。。还是要依靠数学的力量。。
对于第一个要求,显然就是所有数的最大公约数的因子。
对于第二个要求,显然最小的数是起决定性作用的,所以求一下最小的数满足条件的时候每行最多排多少,就是求最小数的平方根。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,q;
LL a[N];
LL t=-1,mi=1e18;

LL gcd(LL a,LL b)
{
	return b? gcd(b,a%b):a;
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		if(t==-1) t=a[i];
		else t=gcd(a[i],t);
		mi=min(a[i],mi);
	}
	
	LL h=(LL)sqrt(mi);
	if(h*h==mi) h--;
	
	scanf("%d",&q);
	while(q--)
	{
		LL x,y;
		scanf("%lld%lld",&x,&y);
		if(y==1) 
		{
			if(t%x!=0) puts("No");
			else puts("Yes");
		}
		else 
		{
			if(x<=h) puts("Yes");
			else puts("No");
		}
	}



	return 0;
}
/*

*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值