题目链接:hdu6287
题意:给你n个数,和m个询问,每个询问有一个l和r和d,现在问你,从【l,r】区间的乘积是不是d的倍数。
思路:对于一个数k是不是d的倍数这类问题,我们可以对这两个数分解质因数,之后看看k的质因数和d的质因数之间的关系,如果满足对于d的每一个质因数个数,在k中都有出现过,且k的出现次数要大于等于d的出现次数,这个就是满足的。
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
int n,m;
while(t--)
{
cin>>n>>m;
int a[100010];
for(int i=0; i<n; i++)
cin>>a[i];
vector<int>prime[100005];//将每个存在该质因数的对应下标存入质数数组内
for(int i=0; i<n; i++)
{
int k=sqrt(a[i]);
for(int j=2; j<=k; j++)
if(a[i]%j==0)
{
while(a[i]%j==0)
prime[j].push_back(i), a[i]/=j;
}
if(a[i]>1)
prime[a[i]].push_back(i);
}
while(m--)
{
int l,r,d;
cin>>l>>r>>d;
l--;
r--;
int flag=0;
int k=sqrt((d));
for(int i=2; i<=k; i++)
if(d%i==0)
{
int cnt=0;
while(d%i==0)
d/=i,cnt++;
if(upper_bound(prime[i].begin(),prime[i].end(),r)-lower_bound(prime[i].begin(),prime[i].end(),l)<cnt)
{
flag=1;
break;
}
}
if(d>1)
{
int pos = upper_bound(prime[d].begin(), prime[d].end(),r) -
lower_bound(prime[d].begin(), prime[d].end(),l);
if(pos==0)flag=1;
}
if(flag)
cout<<"No\n";
else
cout<<"Yes\n";
}
}
return 0;
}