Submission #479857

#TimeUsernameProblemLanguageResultExecution timeMemory
479857couplefireDistributing Candies (IOI21_candies)C++17
100 / 100
557 ms46876 KiB
#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 1<<18;

struct node{ll sum, mn, mx;} tree[N<<1];
int n, q, cap[N], q_l[N], q_r[N], val[N];
vector<int> start[N], stop[N], res;

node comb(node a, node b){
    node res; res.sum = a.sum+b.sum;
    res.mn = min(a.mn, a.sum+b.mn);
    res.mx = max(a.mx, a.sum+b.mx);
    return res;
}

void upd(int pos, int nval, int v = 1, int tl = 0, int tr = N-1){
    if(tr<pos || tl>pos) return;
    if(tl==tr) return void(tree[v] = {nval, min(nval, 0), max(nval, 0)});
    int tm = (tl+tr)>>1;
    upd(pos, nval, v<<1, tl, tm);
    upd(pos, nval, v<<1|1, tm+1, tr);
    tree[v] = comb(tree[v<<1], tree[v<<1|1]);
}

node get(int l, int r, int v = 1, int tl = 0, int tr = N-1){
    if(tr<l || tl>r) return {0, (ll)1e18, -(ll)1e18};
    if(l<=tl && tr<=r) return tree[v];
    int tm = (tl+tr)>>1;
    return comb(get(l, r, v<<1, tl, tm), get(l, r, v<<1|1, tm+1, tr));
}

int find(int bd, node nxt, int v = 1, int tl = 0, int tr = N-1){
    node tmp = comb(tree[v], nxt);
    if(tmp.mx-tmp.mn<(ll)bd) return -1;
    if(tl==tr) return tl;
    int tm = (tl+tr)>>1;
    int x = find(bd, nxt, v<<1|1, tm+1, tr);
    if(x>=0) return x;
    return find(bd, comb(tree[v<<1|1], nxt), v<<1, tl, tm);
}

vector<int> distribute_candies(vector<int> _c, vector<int> _l, vector<int> _r, vector<int> _v){
    n = _c.size(), q = _l.size();
    for(int i = 0; i<n; ++i) cap[i] = _c[i];
    for(int i = 0; i<q; ++i)
        q_l[i] = _l[i], q_r[i] = _r[i], val[i] = _v[i];
    for(int i = 0; i<q; ++i)
        start[q_l[i]].push_back(i), stop[q_r[i]].push_back(i);
    res.resize(n);
    for(int i = 0; i<n; ++i){
        for(auto x : start[i]) upd(x, val[x]);
        int pos = find(cap[i], {0, 0, 0});
        node cur = get(max(pos, 0), N-1);
        if(pos==-1 || cur.mx==0ll) res[i] = cur.sum-cur.mn;
        else res[i] = (ll)cap[i]-cur.mx+cur.sum;
        for(auto x : stop[i]) upd(x, 0);
    } return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...