题解:
分段
当p<=100时候,暴力枚举%p=k的个数
当p>100是,暴力枚举j=qp+k的个数
代码:
#include<bits/stdc++.h> using namespace std; const int N=200005,M=10005,K=105; int a[N],b[N],m,n,k[N],f1[K][K],f2[M],f[N],p[N],ans[N]; int cmp(int x,int y) { return a[x]<a[y]; } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++)scanf("%d",&b[i]); for (int i=1;i<=m;i++) { scanf("%d%d%d%d",&a[i+m],&a[i],&p[i],&k[i]); a[i+m]--;f[i]=i;f[i+m]=i+m;p[i+m]=p[i];k[i+m]=k[i]; } sort(f+1,f+m+m+1,cmp); int l=1; while (a[f[l]]==0)l++; for (int i=1;i<=n;i++) { for (int j=1;j<=100;j++)f1[j][b[i]%j]++; f2[b[i]]++; while (a[f[l]]==i) { if (f[l]>m) { if (p[f[l]]>100) for (int j=k[f[l]];j<=10000;j+=p[f[l]])ans[f[l]-m]-=f2[j]; else ans[f[l]-m]-=f1[p[f[l]]][k[f[l]]]; l++; } else { if (p[f[l]]>100) for (int j=k[f[l]];j<=10000;j+=p[f[l]])ans[f[l]]+=f2[j]; else ans[f[l]]+=f1[p[f[l]]][k[f[l]]]; l++; } } } for (int i=1;i<=m;i++)printf("%d\n",ans[i]); }