Submission #1171294

#TimeUsernameProblemLanguageResultExecution timeMemory
1171294Zbyszek99Two Dishes (JOI19_dishes)C++20
82 / 100
1116 ms229656 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#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;

const int tree_siz = 1024*2048-1;
ll drzewo[tree_siz];
ll spych_set[tree_siz];
ll spych_add[tree_siz];

void spych(int v)
{
    if(spych_set[v-1] != -1e18)
    {
        drzewo[v*2-1] = spych_set[v-1];
        drzewo[v*2] = spych_set[v-1];
        spych_set[v*2-1] = spych_set[v-1];
        spych_set[v*2] = spych_set[v-1];
        spych_add[v*2-1] = 0;
        spych_add[v*2] = 0;
        spych_set[v-1] = -1e18;
        spych_add[v-1] = 0;
    }
    else
    {
        drzewo[v*2-1] += spych_add[v-1];
        drzewo[v*2] += spych_add[v-1];
        if(spych_set[v*2-1] == -1e18)
        {
            spych_add[v*2-1] += spych_add[v-1];
        }
        else
        {
            spych_set[v*2-1] += spych_add[v-1];
        }
        if(spych_set[v*2] == -1e18)
        {
            spych_add[v*2] += spych_add[v-1];
        }
        else
        {
            spych_set[v*2] += spych_add[v-1];
        }
        spych_add[v-1] = 0;
    }
}

void upd(int akt)
{
    drzewo[akt-1] = max(drzewo[akt*2-1],drzewo[akt*2]);
}

void set_val(int akt, int p1, int p2, int s1, int s2, ll val)
{
    if(p2 < s1 || p1 > s2) return;
    if(p1 >= s1 && p2 <= s2)
    {
        drzewo[akt-1] = val;
        spych_set[akt-1] = val;
        spych_add[akt-1] = 0;
        return;
    }
    spych(akt);
    set_val(akt*2,p1,(p1+p2)/2,s1,s2,val);
    set_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2,val);
    upd(akt);
}

void add_val(int akt, int p1, int p2, int s1, int s2, ll val)
{
    if(p2 < s1 || p1 > s2) return;
    if(p1 >= s1 && p2 <= s2)
    {
        drzewo[akt-1] += val;
        if(spych_set[akt-1] == -1e18) spych_add[akt-1] += val;
        else spych_set[akt-1] += val;
        return;
    }
    spych(akt);
    add_val(akt*2,p1,(p1+p2)/2,s1,s2,val);
    add_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2,val);
    upd(akt);
}

ll get_val(int akt, int p1, int p2, int s1, int s2)
{
    if(p2 < s1 || p1 > s2) return -1e18;
    if(p1 >= s1 && p2 <= s2)
    {
        return drzewo[akt-1];
    }
    spych(akt);
    ll w1 = get_val(akt*2,p1,(p1+p2)/2,s1,s2);
    ll w2 = get_val(akt*2+1,(p1+p2)/2+1,p2,s1,s2);
    upd(akt);
    return max(w1,w2);
}

int poz_greater(int akt, int l, int r, ll x)
{
    if(l == r) return l;
    spych(akt);
    if(drzewo[akt*2-1] >= x) return poz_greater(akt*2,l,(l+r)/2,x);
    return poz_greater(akt*2+1,(l+r)/2+1,r,x);
}

int find_greater(int akt, int p1, int p2, int s1, int s2, ll x)
{
    if(p2 < s1 || p1 > s2) return -1;
    if(p1 >= s1 && p2 <= s2)
    {
        if(drzewo[akt-1] >= x)
        {
            return poz_greater(akt,p1,p2,x);
        }
        return -1;
    }
    spych(akt);
    int w1 = find_greater(akt*2,p1,(p1+p2)/2,s1,s2,x);
    if(w1 == -1)
    {
        w1 = find_greater(akt*2+1,(p1+p2)/2+1,p2,s1,s2,x);
    }
    upd(akt);
    return w1;
}


ll pref_sum[1000'002][2];
ll S[1000'002][2];
ll C[1000'002][2];
map<int,ll> events_map[1000'002];
vector<pll> events[1000'002];
ll def_ans;

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //random_start();
    rep(i,tree_siz)
    {
        drzewo[i] = -1e18;
        spych_set[i] = -1e18;
        spych_add[i] = -1e18;
    }
    int n,m;
    cin >> n >> m;
    set_val(1,0,tree_siz/2,0,m,0);
    rep2(i,1,n)
    {
        ll a;
        cin >> a >> S[i][0] >> C[i][0];
        pref_sum[i][0] = pref_sum[i-1][0] + a;
    }
    rep2(i,1,m)
    {
        ll a;
        cin >> a >> S[i][1] >> C[i][1];
        pref_sum[i][1] = pref_sum[i-1][1] + a;
    }
    pref_sum[n+1][0] = pref_sum[n][0];
    rep2(i,1,n)
    {
        int l = 0;
        int r = m;
        int ans = -1;
        while(l <= r)
        {
            int mid = (l+r)/2;
            if(pref_sum[mid][1] + pref_sum[i][0] <= S[i][0])
            {
                ans = mid;
                l = mid+1;
            }
            else
            {
                r = mid-1;
            }
        }
       // cerr << i << " " << ans << " lim1\n";
        if(ans != -1)
        {
            events_map[i][ans] += C[i][0];
        }
    }
    rep2(i,1,m)
    {
        int l = 0;
        int r = n+1;
        int ans = -1;
        while(l <= r)
        {
            int mid = (l+r)/2;
            if(pref_sum[mid][0] + pref_sum[i][1] <= S[i][1])
            {
                ans = mid;
                l = mid+1;
            }
            else
            {
                r = mid-1;
            }
        }
      //  cerr << i << " " << ans << " lim2\n";
        if(ans != -1)
        {
            def_ans += C[i][1];
            events_map[ans+1][i-1] += -C[i][1];
        }
    }
    rep2(i,0,n)
    {
        forall(it,events_map[i])
        {
            events[i].pb({it.ff,it.ss});
        }
        sort(all(events[i]));
        reverse(all(events[i]));
    }
    rep2(i,0,n)
    {
        sort(all(events[i]));
        reverse(all(events[i]));
    }
    rep2(i,0,n)
    {
      //  cerr << i << " i:\n\n";
        forall(it,events[i])
        {
            //cerr << it.ff << " " << it.ss << " event!!!!\n";
            add_val(1,0,tree_siz/2,0,it.ff,it.ss);
            ll new_pref_max = get_val(1,0,tree_siz/2,it.ff,it.ff);
         //   cerr << new_pref_max << " new_max\n";
            if(it.ff+1 <= m)
            {
                int pref = find_greater(1,0,tree_siz/2,it.ff+1,m,new_pref_max);
            // cerr << pref << " pref\n";
                if(pref == -1) pref = m+1;
            // cerr << pref << " pref\n";
                if(pref != it.ff+1)
                {
                    set_val(1,0,tree_siz/2,it.ff+1,pref-1,new_pref_max);
                }
            }
        }
       // rep2(j,0,m)
       // {
       //     cerr << get_val(1,0,tree_siz/2,j,j) << " ";
       // }
       // cerr << " dp\n";
    }
  //  cerr << def_ans << " def\n";
    cout << def_ans + get_val(1,0,tree_siz/2,m,m) << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...