【题目】
【题意】
给定一个长度为n的序列,给出m个询问l,r,x,如果序列中下标为l的项到下标为r的项的乘积是x的倍数,输出Yes,否则输出No。
【思路】
将序列的项与输入的x分解质因子,用二分求出从下标l到r的x的质因子的数目,通过比较从下标l到r的x的质因子的数目与x自身的质因子的数目来判断是否整除。
【代码】
#include <bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
vector <int> vec[maxn];
int cnt[maxn];
void solve(int x,int pos)
{
for(int i=2;i*i<=x;i++)
while(x%i==0)
vec[i].push_back(pos),x/=i;
if(x>1) vec[x].push_back(pos);
}
int fun(int l,int r,int x)
{
return upper_bound(vec[x].begin(),vec[x].end(),r)-lower_bound(vec[x].begin(),vec[x].end(),l);
}
int main()
{
int t; scanf("%d",&t);
while(t--){
for(int i=1;i<=100000;i++)
vec[i].clear();
int n,m; scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int x; scanf("%d",&x);
solve(x,i);
}
while(m--){
int l,r,d; scanf("%d%d%d",&l,&r,&d);
int f=1;
for(int i=2;i*i<=d;i++){
if(d%i==0){
int cou=0;
while(d%i==0) cou++,d/=i;
//printf("%d:%d,%d\n",i,cou,fun(l,r,i));
if(fun(l,r,i)<cou){
f=0; break;
}
}
}
if(d>1&&!fun(l,r,d)) f=0;
if(f) puts("Yes");
else puts("No");
}
}
return 0;
}