Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#define INF 0x7fffffff
#define SUP 0x80000000
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int N=1000007;
int tot;
int pri[N];
bool valid[10*N];
int s[N];
int cnt[10*N];
void GetPri()
{
mem(valid,true);
mem(s,0);
valid[1]=false;
tot=0;
for(int i=2;i<=10000000;i++)
{
if(valid[i])
{
pri[++tot]=i;
s[tot]=s[tot-1]+cnt[i]; //维护前缀和
for(int j=i+i;j<=10000000;j+=i)
{
s[tot]+=cnt[j]; //利用筛法的性质
valid[j]=false;
}
}
}
//for(int i=1;i<=10;i++)
// printf("%d %d\n",pri[i],s[i]);
}
int main()
{
int n,m,v;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&v);
cnt[v]++;
}
GetPri();
pri[++tot]=(1<<31-1);
int l,r,x,y;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d%d",&l,&r);
x=lower_bound(pri+1,pri+tot,l)-pri;
y=upper_bound(pri+1,pri+tot,r)-pri-1;
//cout<<x<<"^"<<y<<endl;
if(x<=y)
printf("%d\n",s[y]-s[x-1]);
else
printf("0\n");
}
return 0;
}
//好吧=_=!
//下面是我的脑残代码(线晒+合数分解+树状树状+二分)
//就权且当模板用吧。
/*
int pri[N];
bool valid[10000007];
int dp[N];
int c[N];
int tot;
void getpri()
{
mem(valid,true);
tot=0;valid[1]=false;
for(int i=2;i<=10000000;i++)
{
if(valid[i]) pri[++tot]=i;
for(int j=1;(j<=tot)&&(i*pri[j]<=10000000);j++)
{
valid[i*pri[j]]=false; Ïê¼ûºìiutyuop¡¾
if(i%pri[j]==0) break;
}//cout<<"--"<<endl;
}
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
for(int i=x;i<=tot;i+=lowbit(i))
c[i]+=v;
}
int sum(int x)
{
if(dp[x]!=-1) return dp[x];
int ret=0;
for(int i=x;i>0;i-=lowbit(i))
ret+=c[i];
dp[x]=ret;
return ret;
}
void pribreak(int x)
{
for(int i=1;i<=tot;i++)
{
if(x%pri[i]==0){
add(i,1);
}
while(x%pri[i]==0)
{
x/=pri[i];
}
if(x==1)
return;
}
}
int main()
{
int n,m;
getpri();
pri[++tot]=(1<<31-1);
while(scanf("%d",&n)==1)
{
int a;
mem(c,0);
mem(dp,-1);
for(int i=0;i<n;i++)
{
scanf("%d",&a);
pribreak(a);
}
//for(int i=1;i<=10;i++)
// printf("%d %d--\n",pri[i],c[i]);
scanf("%d",&m);
int l,r,x,y;
for(int i=0;i<m;i++)
{
scanf("%d%d",&l,&r);
x=lower_bound(pri+1,pri+tot,l)-pri;
y=upper_bound(pri+1,pri+tot,r)-pri-1;
if(x<=y)
printf("%d\n",sum(y)-sum(x-1));
else
printf("0\n");
}
}
return 0;
}
*/