http://acm.hdu.edu.cn/showproblem.php?pid=6287
这题本来可以用二维数组搞一个所有数的质因子及其次幂的前缀和 然后每次线性枚举一遍素因子 但是空间爆炸 用主席树的话每次只需更新几条链 牺牲了时间复杂度 增加了一个log 虽然这样用主席树空间耗费也大 但是题目时空限制都很松
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
struct node1
{
int l;
int r;
int val;
};
struct node2
{
int pos;
int val;
};
node1 tree[4000010];
vector <node2> ary[100010];
int mp[100010],book[100010],prime[10010],root[500010];
int n,q,len,now,num;
void init()
{
node2 tmp;
int i,j,cnt,val;
book[1]=1;
for(i=1;i*i<=100000;i++)
{
if(!book[i])
{
for(j=i+i;j<=100000;j+=i)
{
book[j]=1;
}
}
}
len=0;
for(i=1;i<=100000;i++)
{
if(!book[i])
{
len++;
prime[len]=i;
}
}
for(i=2;i<=100000;i++)
{
val=i;
for(j=2;j*j<=val;j++)
{
cnt=0;
while(val%j==0)
{
cnt++;
val/=j;
}
if(cnt)
{
tmp.pos=lower_bound(prime+1,prime+len+1,j)-prime;
tmp.val=cnt;
ary[i].push_back(tmp);
}
}
if(val>1)
{
tmp.pos=lower_bound(prime+1,prime+len+1,val)-prime;
tmp.val=1;
ary[i].push_back(tmp);
}
}
}
int build(int l,int r)
{
int cur,m;
cur=num++;
tree[cur].l=0,tree[cur].r=0,tree[cur].val=0;
if(l==r) return cur;
m=(l+r)/2;
tree[cur].l=build(l,m);
tree[cur].r=build(m+1,r);
return cur;
}
int update(int rot,int tar,int val,int l,int r)
{
int cur,m;
cur=num++;
tree[cur]=tree[rot];
tree[cur].val+=val;
if(l==r) return cur;
m=(l+r)/2;
if(tar<=m) tree[cur].l=update(tree[rot].l,tar,val,l,m);
else tree[cur].r=update(tree[rot].r,tar,val,m+1,r);
return cur;
}
int query(int lrot,int rrot,int tar,int l,int r)
{
int m;
if(l==r) return tree[rrot].val-tree[lrot].val;
m=(l+r)/2;
if(tar<=m) return query(tree[lrot].l,tree[rrot].l,tar,l,m);
else return query(tree[lrot].r,tree[rrot].r,tar,m+1,r);
}
int main()
{
int t,i,j,cnt,l,r,val,flag,res;
init();
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
mp[0]=0;
now=0,num=0;
root[now]=build(1,len);
now++;
for(i=1;i<=n;i++)
{
scanf("%d",&val);
for(j=0;j<ary[val].size();j++)
{
if(ary[val][j].val!=0)
{
root[now]=update(root[now-1],ary[val][j].pos,ary[val][j].val,1,len);
now++;
}
}
mp[i]=now-1;
}
while(q--)
{
scanf("%d%d%d",&l,&r,&val);
flag=1;
for(i=0;i<ary[val].size();i++)
{
res=query(root[mp[l-1]],root[mp[r]],ary[val][i].pos,1,len);
if(res<ary[val][i].val)
{
flag=0;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
}
return 0;
}