BZOJ2506 calc

首先我们发现这个区间特别的蛋疼……所以我们离线,把询问拆成两个,然后从前往后扫整个序列

对于p<=100的,拿个数组记录所有模p得k的,到时候直接出解,对于p>100的,开个数组记录值为多少的都有多少个,然后暴力

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 200010
#define MAXM 110
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
struct que{
	int x;
	int p;
	int k;
	int bel;
	int f;
	que(){
		
	}
	que(int _x,int _p,int _k,int _bel,int _f){
		x=_x;
		p=_p;
		k=_k;
		bel=_bel;
		f=_f;
	}
	friend bool operator <(que x,que y){
		return x.x<y.x;
	}
};
int n,m;
int a[MAXN];
que q[MAXN];
int s[MAXM][MAXM];
int c[MAXN];
int ans[MAXN];
int main(){
	freopen("data.txt","r",stdin);
	freopen("dui.txt","w",stdout);
	int i,j;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(i=1;i<=m;i++){
		scanf("%d%d%d%d",&q[i*2-1].x,&q[i*2].x,&q[i*2-1].p,&q[i*2-1].k);
		q[i*2].p=q[i*2-1].p;
		q[i*2].k=q[i*2-1].k;
		q[i*2].bel=q[i*2-1].bel=i;
		q[i*2-1].x--;
		q[i*2-1].f=-1;
		q[i*2].f=1;
	}
	sort(q+1,q+2*m+1);
	int wzh=1;
	while(q[wzh].x==0){
		wzh++;
	}
	for(i=1;i<=n;i++){
		for(j=1;j<=100;j++){
			s[j][a[i]%j]++;
		}
		c[a[i]]++;
		while(q[wzh].x==i){
			if(q[wzh].p<=100){
				ans[q[wzh].bel]+=q[wzh].f*s[q[wzh].p][q[wzh].k];
			}else{
				for(j=q[wzh].k;j<=10000;j+=q[wzh].p){
					ans[q[wzh].bel]+=q[wzh].f*c[j];
				}
			}
			wzh++;
		}
	}
	for(i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}

/*
5 2
1 5 2 3 7
1 3 2 1
2 5 3 0
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值