社区讨论
线段树上二分60ptsTLE求优化
P11217【MX-S4-T1】「yyOI R2」youyou 的垃圾桶参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @m2hguxnp
- 此快照首次捕获于
- 2024/10/20 18:50 去年
- 此快照最后确认于
- 2025/11/04 16:41 4 个月前
CPP
#include<iostream>
#include<algorithm>
#include<cmath>
const int N = 2e5 + 5;
int n, q;
long long w, a[N], sum, p[74] = {0, 1}, tr[N<<2], tag[N<<2], t[74] = {1};
void build(int p, int l, int r) {
if(l == r) {
tr[p] = a[l];
return;
}
int mid = (l+r) >> 1;
build(p*2, l, mid), build(p*2+1, mid+1, r);
tr[p] = tr[p*2] + tr[p*2+1];
}
void push_down(int p, int l, int r) {
int mid = (l+r) >> 1;
tr[p*2] += tag[p]*(mid-l+1);
tr[p*2+1] += tag[p]*(r-mid);
tag[p*2] += tag[p], tag[p*2+1] += tag[p];
tag[p] = 0;
}
void update(int p, int l, int r, int nl, int nr, int k) {
if(l>nr || r<nl) return;
if(nl<=l && r<=nr) {
tr[p] += k*(r-l+1);
tag[p] += k;
return;
}
push_down(p, l, r);
int mid = (l+r) >> 1;
if(l <= mid) update(p*2, l, mid, nl, nr, k);
if(r > mid) update(p*2+1, mid+1, r, nl, nr, k);
tr[p] = tr[p*2] + tr[p*2+1];
}
long long query(int p, int l, int r, int nl, int nr) {
if(l>nr || r<nl) return 0;
if(nl<=l && r<=nr) return tr[p];
push_down(p, l, r);
int mid = (l+r) >> 1;
long long sum = 0;
if(l <= mid) sum += query(p*2, l, mid, nl, nr);
if(r > mid) sum += query(p*2+1, mid+1, r, nl, nr);
return sum;
}
long long solve(long long x) {
int lun = std::lower_bound(p, p+63, ceil(1.*x/sum))-p;
long long ans = n*(lun-1);
x -= p[lun-1]*sum;
int l = 1, r = n, pos;
while(l <= r) {
int mid = (l+r) >> 1;
if(t[lun-1]*query(1, 1, n, 1, mid) >= x) {
pos = mid;
r = mid-1;
}
else l = mid+1;
}
ans += pos-1;
return ans;
}
inline long long read()
{
int X = 0, w = 0; char ch = 0;
while (!isdigit(ch)) {
w |= ch == '-'; ch = getchar(); }
while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
int main () {
for(int i = 1;i <= 63;++i) t[i] = t[i-1]*2;
for(int i = 2;i <= 63;++i) p[i] = 2*p[i-1]+1;
scanf("%d%d%lld", &n, &q, &w);
for(int i = 1;i <= n;++i) scanf("%lld", a+i), sum += a[i];
build(1, 1, n);
while(q--) {
int l, r, d;
l = read(), r = read(), d = read();
sum += (r-l+1)*d;
update(1, 1, n, l, r, d);
printf("%lld\n", solve(w));
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...