1. 程式人生 > >hdu6287 口算訓練(數學+二分)(2018女生賽

hdu6287 口算訓練(數學+二分)(2018女生賽

/*
    hdu6287 口算訓練(數學+二分) by zhuhua
    題意:數量級都是e5,查詢a[l]*...*a[r]%d==0 ? puts("Yes"):puts("No");
    思路:將每個陣列質因數分解,在質因數中儲存出現過的下標,二分求解。
    用素數打個表就t掉了啦。只能這樣每次分解==
*/
#include <bits/stdc++.h>
using namespace std;
const int nmax=100010;
int tot=0,prime[nmax],notprime[nmax];
/*void getprime(){
    int i,j;
    for(i=2;i<nmax;i++){
        if(!notprime[i])
            prime[tot++]=i;
        for(j=0;j<tot&&prime[j]*i<nmax;j++){
            notprime[prime[j]*i]=1;
            if(i%prime[j]==0)break;
        }
    }// cout<<tot<<endl;
}*/

vector <int> appear[nmax];


int main(){
    int a,n,m,t,l,r,d;
    int i,j,cnt;
//    getprime();
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(i=2;i<nmax;i++)appear[i].clear();
        for(i=1;i<=n;i++){
            scanf("%d",&a);
            for(j=2; j*j<=a; j++){
                while(a%j==0){
                    appear[j].push_back(i);
                    a/=j;
                }
            }
            //a是質數
            if(a>1)appear[a].push_back(i);
        }
        for(i=0;i<m;i++){
            scanf("%d%d%d",&l,&r,&d);
            bool flag=true;
            for(j=2; j*j<=d; j++){
                cnt=0;
                while(d%j==0){
                    cnt++;
                    d/=j;
                }
                if(cnt){
                    int has=upper_bound(appear[j].begin(),appear[j].end(),r)-lower_bound(appear[j].begin(),appear[j].end(),l);
                    //cout<<prime[j]<<" "<<cnt<<" "<<has<<endl;
                    if(has<cnt)flag=false;
                }
            }
            if(d>1){
                int has=upper_bound(appear[d].begin(),appear[d].end(),r)-lower_bound(appear[d].begin(),appear[d].end(),l);
                if(has<1)flag=false;
            }
            if(flag)puts("Yes");
            else puts("No");
        }
    }
    return 0;
}