【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;
}
posted @ 2021-08-10 20:42  冰雾  阅读(29)  评论(0编辑  收藏  举报