社区讨论
不会就我线段树+二分炸了吧?
P11217【MX-S4-T1】「yyOI R2」youyou 的垃圾桶参与者 5已保存回复 12
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 12 条
- 当前快照
- 1 份
- 快照标识符
- @m2hj8x3n
- 此快照首次捕获于
- 2024/10/20 19:57 去年
- 此快照最后确认于
- 2025/11/04 23:50 4 个月前
调了一个半小时,炸了
代码:
CPP#include<bits/stdc++.h>
using namespace std;
int n, q, W;
int a[200010], sum[800010], lazy[800010];
void build(int l, int r, int fa) {
if (l == r) {
sum[fa] = a[l];
return;
} else {
int m = l + ((r - l) >> 1);;
build(l, m, fa << 1);
build(m + 1, r, fa << 1 | 1);
sum[fa] = sum[fa << 1] + sum[fa << 1 | 1];
return;
}
}
int query(int l, int r, int s, int t, int fa) {//[l,r] now,[s,t] change,fa = father
if (s <= l && t >= r) return sum[fa];
else {
int m = l + ((r - l) >> 1), s1, s2;
if (lazy[fa]) {
lazy[fa << 1] += lazy[fa], sum[fa << 1] += lazy[fa] * (m - l + 1);
lazy[fa << 1 | 1] += lazy[fa], sum[fa << 1 | 1] += lazy[fa] * (r - m);
}
if (s <= m) s1 = query(l, m, s, t, fa << 1);
if (t > m) s2 = query(m + 1, r, s, t, fa << 1 | 1);
return s1 + s2;
}
}
void update(int l, int r, int fa, int num, int s, int t) {//[l,r] now,[s,t] change,num = change now,fa = father
if (s <= l && t >= r) {
sum[fa] += (r - l + 1) * num, lazy[fa] += num;
return;
} else {
int m = l + ((r - l) >> 1);
if (lazy[fa] && l != r) {
lazy[fa << 1] += lazy[fa], sum[fa << 1] += (m - l + 1) * lazy[fa];
lazy[fa << 1 | 1] += lazy[fa], sum[fa << 1 | 1] += (r - m) * lazy[fa];
lazy[fa] = 0;
}
if (s <= m) update(l, m, fa << 1, num, s, t);
if (t > m) update(m + 1, r, fa << 1 | 1, num, s, t);
sum[fa] = sum[fa << 1] + sum[fa << 1 | 1];
return;
}
}
long long quick_pow(int a, int b) {
long long res = 1;
while (b) {
if (b & 1) res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
int main() {
cin >> n >> q >> W;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
int x = W;
build(1, n, 1);
for (int i = 1; i <= q; i++) {
int l, r, d;
cin >> l >> r >> d;
update(1, n, 1, d, l, r);
int snum = query(1, n, 1, n, 1);
int ans = 0, cnt = 0;
int ll = 0, rr = x / snum;
while (ll < rr) {
int mm = (ll + rr) >> 1;
cout << ll << " " << rr << " " << mm << "\n";
if ((quick_pow(2, mm) - 1) * snum < x) ll = mm + 1, cnt = ll;
else rr = mm - 1;
}
int lll = cnt;
ans = ll * n;
cnt = 0;
x -= (quick_pow(2, lll) - 1) * snum;
cout << x << "\n";
ll = 0, rr = n;
while (ll < rr) {
int mm = (ll + rr) >> 1;
cout << ll << " " << rr << " " << mm << "\n";
if (query(1, n, 1, mm, 1) * quick_pow(2, lll + 1) < x)
l = mm + 1, cnt = mm, cout << query(1, n, 1, mm, 1) << "\n";
else r = mm - 1;
}
cout << ans + cnt << "\n";
x = W;
}
}
/*
6 4 75
9 1 4 5 1 4
1 1 1
3 5 3
3 5 1
3 5 3
ans:
11
9
8
8
*/
有大神说正解 ,但是我就是个学了9个月的小蒟蒻,就写了一个线段树+二分,时间复杂度 ,帮调,互关
回复
共 12 条回复,欢迎继续交流。
正在加载回复...