传送门
题目:
Sample Input
1
5 4
6 4 7 2 5
1 2 24
1 3 18
2 5 17
3 5 35
Sample Output
Yes
No
No
Yes
分析:
直接暴力TLE……
需要换一种思路!
在
1
0
5
10^5
105中质因数组成的个数不会很多,所以可以将质数定为下标,通过对a[i]分解质因数x,若a[i]里质数x有num个则将下标i存入x里,且存num个i;
通过二分查询对应下标看个数是否够即可判断;
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int long long
const int N=1e5+10;
const ll mod=1e+7;
#define eps 1e-8
int cnt=1;
int a[N];
vector<int>s[N];
void dev(int x,int pos){//分解质因数
int c=sqrt(x);
// cout<<"pos="<<pos;
for(int i=2;i<=c;i++){
while(x%i==0){
s[i].push_back(pos);
x/=i;
// cout<<i<<' ';
}
}
if(x>1){
s[x].push_back(pos);
// cout<<x;
}
// cout<<endl;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t,n,m,l,r,d;cin>>t;
while(t--){
cin>>n>>m;
for(int i=2;i<100000;i++)
vector <int>().swap(s[i]);
for(int i=1;i<=n;i++){
cin>>a[i];
// cout<<"a[]="<<a[i]<<endl;
dev(a[i],i);
}
while(m--){
cin>>l>>r>>d;
int c=sqrt(d);int flag=0;
for(int i=2;i<=c;i++){
int num=0;
while(d%i==0){
num++;d/=i;
}
if(num){
if(!s[i].empty()){
int fi=lower_bound(s[i].begin(),s[i].end(),l)-s[i].begin();
int ed=upper_bound(s[i].begin(),s[i].end(),r)-s[i].begin();
// cout<<"i="<<i<<" fi="<<fi<<" ed="<<ed<<endl;
if(ed-fi<num){
flag=1;break;
}
}
else{
flag=1;break;
}
}
}
if(d>1){
int fi=lower_bound(s[d].begin(),s[d].end(),l)-s[d].begin();
int ed=upper_bound(s[d].begin(),s[d].end(),r)-s[d].begin();
if(ed-fi<1)flag=1;
}
if(flag)cout<<"No";
else cout<<"Yes";
// if(m>0)
cout<<endl;
}
// if(t>0)
// cout<<endl;
}
return 0;
}