洛谷 P3948 数据结构 (差分+暴力)

题意:

总结一下就是他有两种操作模式,一种是强制在线,你会有两种操作:A在L,R加上一个数,Q查询他们满足的个数有多少,还有一种是离线的,就是问L,R满足的个数是多少,其中乘上的那个i是总的数组的i而不是查询区间的i,当时以为是查询区间的i所以不会写了。。。之后看了一眼,发现是全局的i,那么就是一道暴力题了。。。

思路:

对于区间加我们直接差分,而对于在线的查询的话,我们直接暴力,由题目可以看出,在线的Q不超过1e3,那么这部分的复杂度就是1e3*8e4 = 8e7 ,之后对于离线的查询,我们先8e4的预处理出满足条件的我们赋为1,之后求一个前缀和,之后就能o1的查询了,离线的查询最多由1e7,所以最后的复杂度是8e7+1e7+8e4 = 9e7 这个复杂度不是太假,直接写就完事儿了

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 8e4+100;
long long C[maxn] , a[maxn];
int main()
{
	int n,opt,mod,MIN,MAX,f;
	char op[3];
	scanf("%d%d%d%d%d",&n,&opt,&mod,&MIN,&MAX);
	for(int i = 0 ; i < opt ; i++)
	{
		scanf("%s",op);
		if(op[0] == 'A')
		{
			int l,r,c;scanf("%d%d%d",&l,&r,&c);
			C[l] += c,C[r+1] -= c;
		}
		else 
		{
			int l,r;scanf("%d%d",&l,&r);
			long long now = 0;
			int ans = 0;
			for(int i = 1; i <= r ; i ++)
			{
				now += C[i];
				if(i>= l && (i * now) % mod >= MIN && (i* now) % mod <= MAX) ans++;
			}
			printf("%d\n",ans);
		}
	}
	scanf("%d",&f);
	for(int i = 1; i <= n ; i++)
	{
		C[i] = C[i] + C[i-1];
		if((C[i] * 1LL * i)%mod >= MIN && (C[i] * 1LL * i)%mod <= MAX) a[i] = 1;
		else a[i] = 0;
		a[i] += a[i-1];
	}
	while(f--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%lld\n",a[r] - a[l-1]);
	}
}

 

展开阅读全文

没有更多推荐了,返回首页