P3948 数据结构
2019-11-07

题目描述

蒟蒻Edt把这个问题交给了你 ———— 一个精通数据结构的大犇,由于是第一题,这个题没那么难。。

edt 现在对于题目进行了如下的简化:

最开始的数组每个元素都是0

给出n,opt,mod,min,max,mod在int范围内

操作A,Q

A: L,R,X 表示把[l,R]这个区间加上X

(数组的从L到R的每个元素都加上X)

Q: L,R表示询问[L,R]这个区间中元素T满足 min<=(T∗i%mod)<=max的 T这样的数的个数(i是数组下标)

(元素的值*数组下标%mod在min到max范围内)

由于 edt 请来了一位非三次元的仓鼠,他帮你用延后了部分问题,将这些询问打入了混乱时空,你的询问操作不会超过1000次,不幸的是,对于延后的询问操作可能有很多次(小于1e7次),但是保证这些延后的询问操作之后不会再次有修改操作

(就是在最后会有很多次询问,但不会进行修改)

Solve

有点混乱,其实有用的话就这两句。
(数组的从L到R的每个元素都加上X)(元素的值*数组下标%mod在min到max范围内)
差分处理,对于前面的询问暴力处理。
而后面的询问用前缀和优化。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 80001
#define ll long long
using namespace std;
ll n,opt,mod,mint,maxt,final;
ll l,r,w;
ll a[N],sum[N];
int main()
{
	scanf("%lld%lld%lld%lld%lld",&n,&opt,&mod,&mint,&maxt);
	for(ll i=1;i<=opt;i++){
		char c;
		cin>>c;
		if(c=='A'){
			scanf("%lld%lld%lld",&l,&r,&w);
			a[l]+=w;
			a[r+1]-=w;
		}
		else{
			scanf("%lld%lld",&l,&r);
			ll now=0,ans=0;
			for(ll j=1;j<=r;j++){
				now+=a[j];
				if(j>=l){
					if((now*j)%mod>=mint&&(now*j)%mod<=maxt) ans++;
				}
			}
			printf("%lld\n",ans);
		}
	}
	for(ll i=1;i<=n;i++){
		a[i]+=a[i-1];
		sum[i]=sum[i-1];
		if((a[i]*i)%mod>=mint&&(a[i]*i)%mod<=maxt) sum[i]++;
	}
	scanf("%lld",&final);
	for(ll i=1;i<=final;i++){
		scanf("%lld%lld",&l,&r);
		printf("%lld\n",sum[r]-sum[l-1]);
	}
	return 0;
}