社区讨论

分块 85 pts 求调

P2122还教室参与者 1已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhjkuw4h
此快照首次捕获于
2025/11/04 04:13
4 个月前
此快照最后确认于
2025/11/04 04:13
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long

const int N = 1e5, T = 405;
int n, m;
int a[N];
int l[T], r[T], belong[N], sum[T], sumc[T], tag[T], block, tot;
int P, Q;

int sqr(int x) {return x * x;}
int gcd(int x, int y) {return y ? (gcd(y, x % y)) : x;}
void change() {int d = gcd(P, Q); P /= d, Q /= d;}

void build()
{
	block = sqrt(n);
	tot = (n + block - 1) / block;
	for (int i = 1; i <= tot; ++i)
	{
		l[i] = (i - 1) * block + 1;
		r[i] = i * block;
	}
	r[tot] = n;
	for (int i = 1; i <= n; ++i)
		belong[i] = (i - 1) / block + 1;
	for (int i = 1; i <= tot; ++i)
		for (int j = l[i]; j <= r[i]; ++j)
			sum[i] += a[j], sumc[i] += sqr(a[j]);
}

void update_part(int L, int R, int K)
{
	for (int i = L; i <= R; ++i)
	{
		sumc[belong[L]] += 2 * a[i] * K + sqr(K);
		a[i] += K;
	}
	sum[belong[L]] += (R - L + 1) * K;
}

void update(int L, int R, int K)
{
	if (belong[L] == belong[R])
	{
		update_part(L, R, K);
		return;
	}
	update_part(L, r[belong[L]], K);
	update_part(l[belong[R]], R, K);
	for (int i = belong[L] + 1; i < belong[R]; ++i)
		tag[i] += K;
}

void query(int L, int R)
{
	int res = 0;
	if (belong[L] == belong[R])
	{
		for (int i = L; i <= R; ++i)
			res += a[i] + tag[belong[i]];
		P = res, Q = (R - L + 1), change();
		return;
	}
	for (int i = L; i <= r[belong[L]]; ++i)
		res += a[i] + tag[belong[i]];
	for (int i = l[belong[R]]; i <= R; ++i)
		res += a[i] + tag[belong[i]];
	for (int i = belong[L] + 1; i < belong[R]; ++i)
		res += sum[i] + (r[i] - l[i] + 1) * tag[i];
	P = res, Q = (R - L + 1), change();
}

void query_c(int L, int R)
{
	int ave = 0, res = 0;
	if (belong[L] == belong[R])
	{
		for (int i = L; i <= R; ++i)
		{
			ave += a[i] + tag[belong[i]];
			res += sqr(a[i] + tag[belong[i]]);
		}
		P = res * (R - L + 1) - sqr(ave), Q = sqr(R - L + 1), change();
		return;
	}
	for (int i = L; i <= r[belong[L]]; ++i)
	{
		ave += a[i] + tag[belong[i]];
		res += sqr(a[i] + tag[belong[i]]);
	}
	for (int i = l[belong[R]]; i <= R; ++i)
	{
		ave += a[i] + tag[belong[i]];
		res += sqr(a[i] + tag[belong[i]]);
	}
	for (int i = belong[L] + 1; i < belong[R]; ++i)
	{
		ave += sum[i] + (r[i] - l[i] + 1) * tag[i];
		res += sumc[i] + 2 * sum[i] * tag[i] + (r[i] - l[i] + 1) * sqr(tag[i]);
	}
	P = res * (R - L + 1) - sqr(ave), Q = sqr(R - L + 1), change();
}

signed main()
{
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i)
		scanf("%lld", a + i);
	build();
	while (m--)
	{
		int op, L, R, K;
		scanf("%lld%lld%lld", &op, &L, &R);
		if (op == 1)
		{
			scanf("%lld", &K);
			update(L, R, K);
		}
		else if (op == 2)
		{
			query(L, R);
			printf("%lld/%lld\n", P, Q);
		}
		else if (op == 3)
		{
			query_c(L, R);
			printf("%lld/%lld\n", P, Q);
		}
	}
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...