Cod sursă (job #769493)

Utilizator avatar Bogdan8765ew Bogdan Nicolaev Bogdan8765ew IP ascuns
Problemă Ștampile Compilator cpp-32 | 2,98 kb
Rundă Arhiva de probleme Status evaluat
Dată 21 mar. 2024 20:41:05 Scor 100
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <map>
 
using namespace std;
 
class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;
 
	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}
 
public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}
 
	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
 
	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};
 
static void solve(void) {
    InParser in ("stampile.in");
    freopen("stampile.out", "w", stdout);
    int N,M;
    in >> N >> M;
    vector<int> zombies(N, 0);
    for(int i=0;i<N;++i) {
      in >> zombies[i];
    }
    map<int, vector<pair<int, int> > > ma;
    int L,R,K;
    for(int i=0;i<M;++i) {
      in >> L >> R >> K;
        --L;
        --R;
        ma[L].emplace_back(R, K);
    }
    long long out = 0;
    long long kill_power = 0;
    map<int, long long> killer_expirations;
    map<int, long long> available_killers;
    for(int at=0;at<N;++at) {
        const auto it = ma.find(at);
        if(it != ma.end()) {
            // add to available_killers
            for(const auto &p : it->second) {
                available_killers[p.first] += p.second;
            }
        }
        while(kill_power < zombies[at]) {
            if(available_killers.empty()) {break;}
            auto it = available_killers.rbegin();
            int to_take = min(zombies[at]-kill_power, it->second);
            //cerr << "TAKING " << to_take << " " << at << " " << it->first << " " << it->second << " " << to_take << endl;
            kill_power += to_take;
            out += to_take;
            killer_expirations[it->first] += to_take;
            if(to_take == it->second) {
                available_killers.erase(it->first);
            }
            else {
                it->second -= to_take;
            }
        }
        if(kill_power < zombies[at]) {
            cout << "-1" << endl;
            return;
        }
        // expire
        if(!killer_expirations.empty()) {
            const auto it = killer_expirations.begin();
            if(it->first == at) {
                kill_power -= it->second;
                killer_expirations.erase(it);
            }
        }
        if(!available_killers.empty()) {
            const auto it = available_killers.begin();
            if(it->first == at) {
                available_killers.erase(it);
            }  
        }
    }
    cout << out << endl;
 
}
 
int main() {
	solve();
	return 0;
}