pedal group的wheel记为p1,extra group的wheel记为e1,e2,tear group的wheel记为t1。
满足target ratio即为p1/e2*e2/t1=P/Q,namely,p1*e2*Q=e1*t1*P。那么可以枚举p1*e2的所有值,在搜索是否存在对应的组合e1*t1满足不等式。
可以预处理将所有的p1*e2存在数组leftarr中,将所有的e1*t1存在数组rightarr中,将leftarr排好序,就可以在给定一个p1*e2的值时,二分查找判断是否存在使得等式成立的e1*t1。
如果二分查找到的e1*t1是同一个extra geal,因为rightarr是排好序的,如果结果是yes,那么mid-1,mid+1处至少存在一个gear可以满足等式并且不是同一个extra geal。否则就不存在满足条件的两个extra geal。
感觉等式两边的值可能会溢出,所以用long long保险些。
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
//2016 Round B Problem B. gWheels
int T;
const int maxn=2010;
int P;
int M;
int Q;
int Np;
int Nt;
int Ne;
long long arrp[maxn];
long long arrt[maxn];
long long arre[maxn];
pair<long long,int>leftarr[maxn*maxn];
pair<long long,int>rightarr[maxn*maxn];
int kgcd(int a,int b)
{
if(a==0) return b;
if(b==0) return a;
if(!(a&1)&&!(b&1)) return kgcd(a>>1,b>>1)<<1;
else if(!(b&1)) return kgcd(a,b>>1);
else if(!(a&1)) return kgcd(a>>1,b);
else return kgcd(abs(a-b),min(a,b));
}
bool cmp(pair<int,int>a,pair<int,int>b)
{
if(a.first==b.first)
{
return a.second<b.second;
}
return a.first<b.first;
}
bool binarysearch(long long val,int idxl)
{
int left=0;
int right=Nt*Ne;
int mid=(left+right)/2;
while(left<=right)
{
mid=(left+right)/2;
long long valr=rightarr[mid].first;
int idxr=rightarr[mid].second;
if(val*Q==valr*P)
{
if(idxl!=idxr)
{
return true;
}
else if(mid>0&&rightarr[mid-1].first==val)
{
return true;
}
else if(mid<Nt*Ne-1&&rightarr[mid+1].first==val)
{
return true;
}
return false;
}
else if(val*Q<valr*P)//valr is too large
{
right=mid-1;
}
else if(val*Q>valr*P)//valr is too small
{
left=mid+1;
}
}
return false;
}
int main()
{
freopen("B-large-practice.in","r",stdin);
// freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
printf("Case #%d:\n",ca);
memset(arrp,0,sizeof(arrp));
memset(arrt,0,sizeof(arrt));
memset(arre,0,sizeof(arre));
scanf("%d %d %d",&Np,&Ne,&Nt);
for(int i=0;i<Np;i++)
{
scanf("%lld",&arrp[i]);
}
for(int i=0;i<Ne;i++)
{
scanf("%lld",&arre[i]);
}
for(int i=0;i<Nt;i++)
{
scanf("%lld",&arrt[i]);
}
int cnt=0;
for(int i=0;i<Np;i++)
{
for(int j=0;j<Ne;j++)
{
leftarr[cnt++]=make_pair(arrp[i]*arre[j],j);
}
}
cnt=0;
for(int i=0;i<Nt;i++)
{
for(int j=0;j<Ne;j++)
{
rightarr[cnt++]=make_pair(arrt[i]*arre[j],j);
}
}
sort(rightarr,rightarr+cnt,cmp);
scanf("%d",&M);
for(int i=0;i<M;i++)
{
scanf("%d %d",&P,&Q);
int g=kgcd(P,Q);
P/=g;
Q/=g;
bool ans=false;
for(int i=0;i<Np*Ne;i++)
{
ans=binarysearch(leftarr[i].first,leftarr[i].second);
if(ans==true)
{
printf("Yes\n");
break;
}
}
if(ans==false)
{
printf("No\n");
}
}
}
return 0;
}