传送门biu~
绝对是思路神题。把询问离线并分类:如果询问的
p≤100
p
≤
100
,我们完全可以暴力维护
fi,j
f
i
,
j
表示
modi
mod
i
等于
j
j
的数有多少个;如果询问的,那么在
10000
10000
内的所有正整数中
modp=k
mod
p
=
k
的数最多只能有100个,可以暴力枚举。所以把这两种询问分开处理。
#include<bits/stdc++.h>
using namespace std;
struct data{int id,opt,p,k,num;}q[200005];int tp;
inline bool cmp(data a,data b){return a.num<b.num;}
int a[100005],f[105][105],g[10005],an[100005][2];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=m;++i){
int l,r,p,k;
scanf("%d%d%d%d",&l,&r,&p,&k);
q[++tp].id=i;q[tp].opt=0;q[tp].p=p;q[tp].k=k;q[tp].num=r;
q[++tp].id=i;q[tp].opt=1;q[tp].p=p;q[tp].k=k;q[tp].num=l-1;
}
sort(q+1,q+tp+1,cmp);
int now=0;
for(int i=1;i<=tp;++i){
while(now<q[i].num){
++now;
for(int j=1;j<=100;++j) ++f[j][a[now]%j];
++g[a[now]];
}
if(q[i].p<=100) an[q[i].id][q[i].opt]=f[q[i].p][q[i].k];
else for(int j=q[i].k;j<=10000;j+=q[i].p) an[q[i].id][q[i].opt]+=g[j];
}
for(int i=1;i<=m;++i) printf("%d\n",an[i][0]-an[i][1]);
return 0;
}