Pagini recente »
Borderou de evaluare (job #263721)
|
Istoria paginii utilizator/carmenminca
|
Borderou de evaluare (job #688051)
|
Istoria paginii utilizator/contulastanulmaiuit
|
Cod sursă (job #769493)
Cod sursă (job
#769493)
#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;
}