hdu6287 口算訓練(數學+二分)(2018女生賽
阿新 • • 發佈:2018-12-16
/* 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; }