【JZOJ4744】同余
【JZOJ4744】同余
by AmanoKumiko
Description
给出序列a
多组询问求
\[Σ_{i=l}^{r}[a[i]≡q(modp)]
\]
Input
n,m
a1...an
l1 r1 p1 q1
...
lm rm pm qm
Output
m行,每行包含一个整数,表示答案
Sample Input
5 2
1 5 2 3 7
1 3 2 1
2 5 3 0
Sample Output
2
1
Data Constraint
对于100%的数据,n,m,l,r≤100000,0≤q<p≤10000,0≤ai≤10000。
Solution
分块能力还是不行啊///
看到10000马上想到\(n\sqrt p\)
离线
p>100可以直接枚举
p<=100开个\(g[i][j]\)表示模\(i\)为\(j\)的方案数(岂可修,赛时就差这里没想到)
Code
#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define N 100010
int ans[N],n,m,a[N],t[10010],g[110][110],l,r,p,q,tot,h;
struct node{int x,p,q,pos,kind;}ask[N*2];
bool cmp(node x,node y){return x.x<y.x;}
int main(){
scanf("%d%d",&n,&m);
F(i,1,n)scanf("%d",&a[i]);
F(i,1,m){
scanf("%d%d%d%d",&l,&r,&p,&q);
ask[++tot]=(node){l-1,p,q,i,-1};
ask[++tot]=(node){r,p,q,i,1};
}
sort(ask+1,ask+tot+1,cmp);
F(i,1,tot){
node op=ask[i];
while(h<op.x){
h++;
t[a[h]]++;
F(j,1,100)g[j][a[h]%j]++;
}
if(op.p<=100)ans[op.pos]+=op.kind*g[op.p][op.q];
else{F(j,0,(10000-op.q)/op.p)ans[op.pos]+=op.kind*t[j*op.p+op.q];}
}
F(i,1,m)printf("%d\n",ans[i]);
return 0;
}