제출 #1328055

#제출 시각아이디문제언어결과실행 시간메모리
1328055Zbyszek99Ants and Sugar (JOI22_sugar)C++20
100 / 100
1766 ms97740 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;

struct query
{
    int t,p,a;
};

const int tree_siz = 1024*1024-1;

struct segtree
{
    bool type = 0;
    ll val[tree_siz+1];
    ll oper[tree_siz+1];
    void reset(int t)
    {
        type = t;
        rep2(i,1,tree_siz)
        {
            oper[i] = 0;
            val[i] = 0;
        }
    }
    ll f(ll x, ll y)
    {
        if(type) return max(x,y);
        return min(x,y);
    }
    void spych(int akt)
    {
        val[akt*2] += oper[akt];
        val[akt*2+1] += oper[akt];
        oper[akt*2] += oper[akt];
        oper[akt*2+1] += oper[akt];
        oper[akt] = 0;
    }
    void add_seg(int akt, int p1, int p2, int s1, int s2, ll x)
    {
        if(p2 < s1 || p1 > s2) return;
        if(p1 >= s1 && p2 <= s2)
        {
            val[akt] += x;
            oper[akt] += x;
            return;
        }
        spych(akt);
        add_seg(akt*2,p1,(p1+p2)/2,s1,s2,x);
        add_seg(akt*2+1,(p1+p2)/2+1,p2,s1,s2,x);
        val[akt] = f(val[akt*2],val[akt*2+1]);
    }
    ll get_val(int akt, int p1, int p2, int s1, int s2)
    {
        if(p2 < s1 || p1 > s2) return {type ? (ll)-1e18 : (ll)1e18};
        if(p1 >= s1 && p2 <= s2) return val[akt];
        spych(akt);
        return f(get_val(akt*2,p1,(p1+p2)/2,s1,s2),get_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2));
    }
};

vi ls;
map<int,int> mp;
ll cur_ans = 0;
ll can_add[500001];
segtree tree_left;
segtree tree_right;
set<int> active_non;
int L;

bool try_add(int poz)
{
    int p = mp[poz];
    ll add = min(can_add[p],tree_right.get_val(1,0,tree_siz/2,p,tree_siz/2)-tree_left.get_val(1,0,tree_siz/2,0,p));
    if(add == 0) return 0;
    can_add[p] -= add;
    cur_ans += add;
    tree_right.add_seg(1,0,tree_siz/2,p,tree_siz/2,-add);
    tree_left.add_seg(1,0,tree_siz/2,p+1,tree_siz/2,-add);
    if(can_add[p] == 0)
    {
        active_non.erase(poz);
        return 1;
    }
    return 0;
}

void add2(int poz, int k)
{
    int l = 1;
    int r = siz(ls)-1;
    int add_suf = siz(ls);
    while(l <= r)
    {
        int mid = (l+r)/2;
        if(ls[mid]+L >= poz)
        {
            add_suf = mid;
            r = mid-1;
        }
        else
        {
            l = mid+1;
        }
    }
    tree_right.add_seg(1,0,tree_siz/2,add_suf,tree_siz/2,k);
    l = 1;
    r = siz(ls)-1;
    add_suf = siz(ls);
    while(l <= r)
    {
        int mid = (l+r)/2;
        if(ls[mid]-L > poz)
        {
            add_suf = mid;
            r = mid-1;
        }
        else
        {
            l = mid+1;
        }
    }
    tree_left.add_seg(1,0,tree_siz/2,add_suf,tree_siz/2,k);
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //random_start();
    int q;
    cin >> q >> L;
    tree_left.reset(1);
    tree_right.reset(0);
    vector<query> queries;
    rep(qq,q)
    {
        int t,p,a;
        cin >> t >> p >> a;
        queries.pb({t,p,a});
        if(t == 1) mp[p] = 1;
    }
    int cur = 1;
    ls = {-1};
    forall(it,mp)
    {
        ls.pb(it.ff);
        mp[it.ff] = cur++;
    } 
    forall(it,queries)
    {
        if(it.t == 1)
        {
            can_add[mp[it.p]] += it.a;
            active_non.insert(it.p);
            try_add(it.p);
        }
        else
        {
            add2(it.p,it.a);
            while(true)
            {
                auto it2 = active_non.lower_bound(it.p);
                if(it2 == active_non.end()) break;
                if(!try_add(*it2)) break;
            }
            while(true)
            {
                auto it2 = active_non.lower_bound(it.p);
                if(it2 == active_non.begin()) break;
                if(!try_add(*(--it2))) break;
            }
        }
        cout << cur_ans << "\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...