思路:
这个题看上去要T掉……但是我们可以对每个数分解质因子,(每个数都可以看成质因子的乘积)然后用vector存每个因子对应的下标,比如说6 4
vec<2>: 1
vec<3>: 1
==========
vec<2>: 2
vec<2>: 2
==========
结果:
vec<2>: 1 2 2
vec<3>: 1
那个l=1,r=2,d=8时:
8=2*2*2
那么在vec<2>里用二分,找到第一个大于等于l的数的下标,和第一个大于r的数的下标,相减为3
8可以分解成3个3,则输出yes
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>
#include<functional>
using namespace std;
#define ll long long
typedef pair<ll,int>P;
const ll INF=1e17+10;
const int N=100005,mod=1e9+7;
int n,m;
int a[N];
vector<int>vec[N];
void solve(int x,int inx){
for(int i=2;i*i<=x;i++){
if(x%i==0){
while(x%i==0){
vec[i].push_back(inx);
x/=i;
}
}
}
if(x!=1)vec[x].push_back(inx);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
solve(a[i],i);
}
int l,r,d;
while(m--){
scanf("%d%d%d",&l,&r,&d);
if(d==1){
printf("Yes\n");
continue;
}
int flag=0;
for(int i=2;i*i<=d;i++){
if(d%i==0){
int num=0;
while(d%i==0){
num++;
d/=i;
}
int L=lower_bound(vec[i].begin(),vec[i].end(),l)-vec[i].begin();
int R=upper_bound(vec[i].begin(),vec[i].end(),r)-vec[i].begin();
if(R-L<num){
flag=1;
break;
}
}
}
if(flag){
printf("No\n");
continue;
}
if(d!=1){
int L=lower_bound(vec[d].begin(),vec[d].end(),l)-vec[d].begin();
int R=upper_bound(vec[d].begin(),vec[d].end(),r)-vec[d].begin();
if(R-L<1){
flag=1;
}
}
if(flag)printf("No\n");
else printf("Yes\n");
}
memset(vec,0,sizeof(vec));
}
}