数列分块入门 2

题目描述
给出一个长为n的数列,以及n个操作,操作涉及区间加法,询问区间内小于某个值x的元素个数。

输入
第一行输入一个数字n。
第二行输入n个数字,第i个数字为a,以空格隔开。
接下来输入n行询问,每行输入四个数字opt、l、 r、c,以空格隔开。若opt =0,表示将位于[l,r]的之间的数字都加 c。
若opt = 1,表示询问[l,r]中,小于c^2的数字的个数。

输出
对于每次询问,输出一行一个数字表示答案。

样例输入
4
1 2 2 3
0 1 3 1
1 1 3 2
1 1 4 1
1 2 3 2
样例输出
3
0
2
提示
1<n ≤50000

类似打一个块状链表的结构,但是没有元素的添加和删除,所以会简单很多。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
typedef long long ll;

int ord[50005];
vector<int>blocks[300];
int num[50005];
int tag[300];
int n;
int len;

void Maintain(int x)
{
	blocks[x].clear();
	for (int i = (x - 1) * len + 1; i <= min(n, x * len); i++) {
		blocks[x].push_back(num[i]);
	}
	sort(blocks[x].begin(), blocks[x].end());
}

void Update(int l, int r, int val)
{
	for (int i = l; i <= min(r, len * ord[l]); i++) {
		num[i] += val;
	}
	Maintain(ord[l]);
	if (ord[l] != ord[r]) {
		for (int i = (ord[r] - 1) * len + 1; i <= r; i++) {
			num[i] += val;
		}
		Maintain(ord[r]);
	}
	for (int i = ord[l] + 1; i <= ord[r] - 1; i++) {
		tag[i] += val;
	}
}

int Query(int l, int r, int val)
{
	int ans = 0;
	for (int i = l; i <= min(r, len * ord[l]); i++) {
		if (num[i] + tag[ord[l]] < val)ans++;
	}
	if (ord[l] != ord[r]) {
		for (int i = (ord[r] - 1) * len + 1; i <= r; i++) {
			if (num[i] + tag[ord[r]] < val)ans++;
		}
	}
	for (int i = ord[l] + 1; i <= ord[r] - 1; i++) {
		int cnt = val - tag[i];
		ans += (lower_bound(blocks[i].begin(), blocks[i].end(), cnt) - blocks[i].begin());
	}
	return ans;
}

int main()
{
	scanf("%d", &n);
	len = sqrt(n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &num[i]);
		ord[i] = (i - 1) / len + 1;
		blocks[ord[i]].push_back(num[i]);
	}
	for (int i = 1; i <= ord[n]; i++) {
		sort(blocks[i].begin(), blocks[i].end());
	}
	for (int i = 1; i <= n; i++) {
		int opt, l, r, c;
		scanf("%d %d %d %d", &opt, &l, &r, &c);
		if (!opt) {
			Update(l, r, c);
		}
		else {
			printf("%d\n", Query(l, r, c * c));
		}
	}
}
posted @   empty_thought  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示