Submission #957015

#TimeUsernameProblemLanguageResultExecution timeMemory
957015Vladth11Overtaking (IOI23_overtaking)C++17
0 / 100
8 ms7120 KiB
#include <bits/stdc++.h>

#include "overtaking.h"
#define int ll

using namespace std;
typedef long long ll;
typedef pair <ll, ll> pii;

const ll NMAX = 1001;
const ll INF = 1e18;
const ll nrbits = 20;
const ll MOD = 998244353;

const pii NEUTRU = {0, 0};

struct Node {
    /// max(x + a, b)
    int st, dr;
    ll maxi; /// basically asta e valoarea lui f(dr)
    pii lazy;
    ll eval(ll x) {
        return max(x + lazy.first, lazy.second);
    }
};

vector <Node> aint;

pii combine(pii nou, pii a) {
    return {a.first + nou.first, max(a.second + nou.first, nou.second)};
}

void propaga(int node, ll st, ll dr) {
    if(node == -1) return;
    if(st != dr) {
        if(aint[node].st == -1) {
            aint[node].st = aint.size();
            aint.push_back({-1, -1, (st + dr) / 2, NEUTRU});
        }
        if(aint[node].dr == -1) {
            aint[node].dr = aint.size();
            aint.push_back({-1, -1, dr, NEUTRU});
        }
        aint[aint[node].st].lazy = combine(aint[node].lazy, aint[aint[node].st].lazy);
        aint[aint[node].dr].lazy = combine(aint[node].lazy, aint[aint[node].dr].lazy);
    }
    aint[node].maxi = aint[node].eval(aint[node].maxi);
    aint[node].lazy = NEUTRU;
}
void update(int node, ll st, ll dr, ll a, ll b, pii functie) {
    propaga(node, st, dr);
    if(a <= st && dr <= b) {
        aint[node].lazy = combine(functie, aint[node].lazy);
        return;
    }
    ll mid = (st + dr) / 2;
    if(a <= mid) {
        if(aint[node].st == -1) {
            aint[node].st = aint.size();
            aint.push_back({-1, -1, mid, NEUTRU});
        }
        update(aint[node].st, st, mid, a, b, functie);
    }
    if(b > mid) {
        if(aint[node].dr == -1) {
            aint[node].dr = aint.size();
            aint.push_back({-1, -1, dr, NEUTRU});
        }
        update(aint[node].dr, mid + 1, dr, a, b, functie);
    }
    propaga(aint[node].st, st, mid);
    propaga(aint[node].dr, mid + 1, dr);
    if(aint[node].dr != -1)
        aint[node].maxi = aint[aint[node].dr].maxi;
    else
        aint[node].maxi = dr;
    /// Calculez valoarea lui f(dr)
}

ll cb(int node, ll st, ll dr, ll val) {
    propaga(node, st, dr);
    if(st == dr) {
        return st;
    }
    ll mid = (st + dr) / 2;
    ll maxist = mid;
    if(aint[node].st != -1) {
        propaga(aint[node].st, st, mid);
        maxist = aint[aint[node].st].maxi;
    }
//    debugs(st);
//    debugs(dr);
//    debug(maxist);
    if(maxist > val) { /// vrem pe alea care au ajuns strict inaintea mea (ca autobuz cartof) - la cazul de egalitate...ori tu (ca de ala de rezerva) esti mai rapid deci e bine ca nu de updatez...ori esti mai incet...deci nici macar nu te voi afecta daca te updatez
        /// mergea si asa, dar pt convenineta am scos pana la urma pe alea mai rapide ca autobuzele de rezerva fiindca nu ne interseaza deloc
        if(aint[node].st == -1) {
            aint[node].st = aint.size();
            aint.push_back({-1, -1, mid, NEUTRU});
        }
        return cb(aint[node].st, st, mid, val);
    }
    if(aint[node].dr == -1) {
        aint[node].dr = aint.size();
        aint.push_back({-1, -1, dr, NEUTRU});
    }
    return cb(aint[node].dr, mid + 1, dr, val);
}

ll query(int node, ll st, ll dr, ll nr, pii acum) {
  	acum = combine(acum, aint[node].lazy);
  	if(st == dr) {
      return max(acum.first + nr, acum.second);
    }
  	ll mid = (st + dr) / 2;
    if(nr <= mid) {
    	if(aint[node].st == -1)
        	 return max(acum.first + nr, acum.second);
        return query(aint[node].st, st, mid, nr, acum);
    }
    if(aint[node].dr == -1)
    	return max(acum.first + nr, acum.second);
    return query(aint[node].dr, mid + 1, dr, nr, acum);
}


ll panaAcum[NMAX];

void init(signed L, signed N, std::vector<long long> T, std::vector<signed> W, signed X, signed M, std::vector<signed> S) {
    vector <int> indici;
    aint.push_back({-1, -1, INF, NEUTRU});
    for(int i = 0; i < N; i++) {
        indici.push_back(i);
        panaAcum[i] = T[i];
    }
    sort(indici.begin(), indici.end(), [&W](const int &a, const int &b) {
        return W[a] > W[b];
    });
    while(indici.size() && W[indici.back()] <= X) {
        indici.pop_back();
    }
    for(int i = 1; i < M; i++) { /// de la 1
        //debug(i);
        sort(indici.begin(), indici.end(), [&W, &panaAcum](const int &a, const int &b) {
            return ((pii){panaAcum[a], W[a]} < (pii){panaAcum[b], W[b]});
        });
        ll maxim = 0;
        vector <ll> unde; /// pt fiecare indice calculam pe cine afecteaza
        for(int j = 0; j < indici.size(); j++) {
            unde.push_back(cb(0, 0, INF, panaAcum[indici[j]]));

        }
        update(0, 0, INF, 0, INF, {1LL * X * (S[i] - S[i - 1]), 0});
        for(int j = 0; j < indici.size(); j++) {
            panaAcum[indici[j]] += 1LL * W[indici[j]] * (S[i] - S[i - 1]);
            maxim = max(maxim, panaAcum[indici[j]]);
            panaAcum[indici[j]] = maxim;
//            debugs(indici[j]);
//            debug(panaAcum[indici[j]]);
//            debug(unde[j]);

            update(0, 0, INF, unde[j], INF, {0, maxim});

        }
    }
}

long long arrival_time(long long Y) {
    return query(0, 0, INF, Y, NEUTRU);
}

Compilation message (stderr)

overtaking.cpp: In function 'void init(int, int, std::vector<long long int>, std::vector<int>, int, int, std::vector<int>)':
overtaking.cpp:143:50: warning: capture of variable 'panaAcum' with non-automatic storage duration
  143 |         sort(indici.begin(), indici.end(), [&W, &panaAcum](const int &a, const int &b) {
      |                                                  ^~~~~~~~
overtaking.cpp:126:4: note: 'll panaAcum [1001]' declared here
  126 | ll panaAcum[NMAX];
      |    ^~~~~~~~
overtaking.cpp:148:26: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  148 |         for(int j = 0; j < indici.size(); j++) {
      |                        ~~^~~~~~~~~~~~~~~
overtaking.cpp:153:26: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  153 |         for(int j = 0; j < indici.size(); j++) {
      |                        ~~^~~~~~~~~~~~~~~
#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...