是有一点思路的,但是因为一直都没有用过vector所以不知道怎么存放。
将所有的序列中的数字都分解质因数,用vector[N]存放,查找时使用lower_bound和upper_bound判断这个序列里所有数总和的这个质数出现的次数是不是大于d中这个质数出现的次数就可以了。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<set>
#include<math.h>
#include<queue>
#include<map>
#include<stack>
#define go(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define ll long long
#define N 100005
using namespace std;
int cnt, prime[N/10];
bool is_prime[N], vis[N];
vector<int> has[N];
void init(){
cnt=0;
is_prime[1]=true;
go(i,2,N-5){
if (!vis[i]){prime[++cnt]=i; vis[i]=true; is_prime[i]=true; }
go(j,1,cnt){
if (i*prime[j]>N-5) break;
vis[i*prime[j]]=true;
if (i%prime[j]==0) break;
}
}
}
int main(){
init();
int T,n,m,x,l,r,d;
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);
go(i,2,N-5) has[i].clear();
go(i,1,n){
scanf("%d",&x);
go(j,1,cnt){
if (x==1) break;
else if (is_prime[x]){
has[x].push_back(i);
break;
}
else{
if (x%prime[j]==0){
while (x%prime[j]==0){
has[prime[j]].push_back(i);
x/=prime[j];
}
}
}
}
}
go(q,1,m){
scanf("%d%d%d",&l,&r,&d);
bool flag=true;
go(i,1,cnt){
if (d==1) break;
else if (is_prime[d]){
if (upper_bound(has[d].begin(),has[d].end(),r)-lower_bound(has[d].begin(),has[d].end(),l)<1) flag=false;
break;
}
else{
int tot=0;
while (d%prime[i]==0){
d/=prime[i];
tot++;
}
int ntot=upper_bound(has[prime[i]].begin(),has[prime[i]].end(),r)-lower_bound(has[prime[i]].begin(),has[prime[i]].end(),l);
if (ntot<tot){
flag=false;
break;
}
}
}
if (flag) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}
STL