1、线段树部分大概没有问题,因为已经过了P1471并且把所有double都改成long long了;
2、gcd没有写挂;
WA on #3#4#5#6#7#8#9#10#11#13,评测记录逛了一圈发现和我一样的不少。
#include <iostream>
using namespace std;
const int N = 1e5;
int n, m;
namespace segment_tree {
long long data1[(N << 2) + 3], data2[(N << 2) + 3], lz[(N << 2) + 3] = {0};
void build(int p, int l, int r) {
if (l == r) {
cin >> data1[p];
data2[p] = data1[p] * data1[p];
return;
}
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
data1[p] = data1[p << 1] + data1[p << 1 | 1];
data2[p] = data2[p << 1] + data2[p << 1 | 1];
return;
}
void pushdown(int p, int l, int r) {
int mid = l + r >> 1;
data2[p << 1] += 2 * lz[p] * data1[p << 1] + (mid - l + 1) * lz[p] * lz[p];
data2[p << 1 | 1] += 2 * lz[p] * data1[p << 1 | 1] + (r - mid) * lz[p] * lz[p];
data1[p << 1] += lz[p] * (mid - l + 1);
data1[p << 1 | 1] += lz[p] * (r - mid);
lz[p << 1] += lz[p];
lz[p << 1 | 1] += lz[p];
lz[p] = 0;
return;
}
void update(int p, int l, int r, int x, int y, int k) {
if (l >= x && r <= y) {
data2[p] += 2 * k * data1[p] + (r - l + 1) * k * k;
data1[p] += k * (r - l + 1);
lz[p] += k;
return;
}
if (lz[p]) pushdown(p, l, r);
int mid = l + r >> 1;
if (x <= mid) update(p << 1, l, mid, x, y, k);
if (y > mid) update(p << 1 | 1, mid + 1, r, x, y, k);
data1[p] = data1[p << 1] + data1[p << 1 | 1];
data2[p] = data2[p << 1] + data2[p << 1 | 1];
return;
}
long long query1(int p, int l, int r, int x, int y) {
if (l >= x && r <= y) return data1[p];
if (lz[p]) pushdown(p, l, r);
int mid = l + r >> 1;
long long res = 0;
if (x <= mid) res += query1(p << 1, l, mid, x, y);
if (y > mid) res += query1(p << 1 | 1, mid + 1, r, x, y);
return res;
}
long long query2(int p, int l, int r, int x, int y) {
if (l >= x && r <= y) return data2[p];
if (lz[p]) pushdown(p, l, r);
int mid = l + r >> 1;
long long res = 0;
if (x <= mid) res += query2(p << 1, l, mid, x, y);
if (y > mid) res += query2(p << 1 | 1, mid + 1, r, x, y);
return res;
}
}
long long gcd(long long a, long long b) {
while (b) {
long long tmp = a;
a = b;
b = tmp % b;
}
return a;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
segment_tree::build(1, 1, n);
while (m--) {
int c, l, r, d;
long long a, b, g, tmp;
cin >> c;
switch (c) {
case 1:
cin >> l >> r >> d;
segment_tree::update(1, 1, n, l, r, d);
break;
case 2:
cin >> l >> r;
a = segment_tree::query1(1, 1, n, l, r), b = r - l + 1;
g = gcd(max(a, b), min(a, b));
cout << a / g << '/' << b / g << '\n';
break;
case 3:
cin >> l >> r;
tmp = segment_tree::query1(1, 1, n, l, r);
a = (r - l + 1) * segment_tree::query2(1, 1, n, l, r) - tmp * tmp, b = (r - l + 1) * (r - l + 1);
g = gcd(max(a, b), min(a, b));
cout << a / g << '/' << b / g << '\n';
break;
}
}
return 0;
}