20分求调
查看原帖
20分求调
571865
JackChen1208楼主2024/12/13 14:05
#include<iostream>
#include<algorithm>
using namespace std;
int n, m;
long long a[500005], sum[500005];
long long d, b, lastDay;
struct node{
    int l, r;
    long long max, sum, time, cover = -1;
}segmentTree[2000005];
int length(int p){
    return segmentTree[p].r - segmentTree[p].l + 1;
}
long long growSum(int p){
    return sum[segmentTree[p].r] - sum[segmentTree[p].l - 1];
}
void build(int l, int r, int p){
    segmentTree[p].l = l, segmentTree[p].r = r;
    if(l == r)  return;
    int mid = (l + r) / 2;
    build(l, mid, 2 * p);
    build(mid + 1, r, 2 * p + 1);
}
void update(int p, int x){
    segmentTree[x].cover = segmentTree[p].cover;    segmentTree[x].time = segmentTree[p].time;
    segmentTree[x].sum = (segmentTree[p].cover != -1 ? length(x) * segmentTree[p].cover : segmentTree[x].sum) + growSum(x) * segmentTree[p].time;
    segmentTree[x].max = (segmentTree[p].cover != -1 ? segmentTree[p].cover : segmentTree[x].max) + a[segmentTree[x].r] * segmentTree[p].time;
}
void pushDown(int p){
    update(p, 2 * p);
    update(p, 2 * p + 1);
    segmentTree[p].cover = -1, segmentTree[p].time = 0;
}
void grow(long long day){
    segmentTree[1].time += day;
    segmentTree[1].sum += growSum(1) * day;
    segmentTree[1].max += a[n] * day;
}
int query(int p, long long val){
    if(segmentTree[p].l == segmentTree[p].r)  return (segmentTree[p].sum > val ? segmentTree[p].l : n + 1);
    pushDown(p);
    if(val < segmentTree[2 * p].max)   return query(2 * p, val);
    else    return query(2 * p + 1, val);
}
void cover(int p, int l, long long val){
    if(l > n)   return;
    if(segmentTree[p].l >= l){
        segmentTree[p].cover = val;    segmentTree[p].time = 0;
        segmentTree[p].sum = length(p) * val;    segmentTree[p].max = val;
        return;
    }
    cover(2 * p + 1, l, val);
    if(l <= segmentTree[2 * p].r)   cover(2 * p, l, val);
    segmentTree[p].sum = segmentTree[2 * p].sum + segmentTree[2 * p + 1].sum;
    segmentTree[p].max = segmentTree[2 * p + 1].max;
}
long long cut(long long day, long long height){
    grow(day);
    long long before = segmentTree[1].sum;
    int l = query(1, height);
    cover(1, l, height);
    return before - segmentTree[1].sum;
}
int main(){
    cin>>n>>m;
    for(int i = 1; i <= n; i++)    cin>>a[i];
    sort(a + 1, a + n + 1);
    for(int i = 1; i <= n; i++) sum[i] = sum[i - 1] + a[i];
    build(1, n, 1);
    for(int i = 1; i <= m; i++){
        cin>>d>>b;
        cout<<cut(d - lastDay, b)<<"\n";
        lastDay = d;
    }
}
2024/12/13 14:05
加载中...