社区讨论
分块 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 条回复,欢迎继续交流。
正在加载回复...