Submission #108921

#TimeUsernameProblemLanguageResultExecution timeMemory
108921hugo_pmTwo Antennas (JOI19_antennas)C++17
100 / 100
1183 ms64124 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
#define form2(i, a, b) for (int i = (a); i < (b); ++i)
#define ford2(i, a, b) for (int i = (a-1); i >= (b); --i)
#define form(i, n) form2(i, 0, n)
#define ford(i, n) ford2(i, n, 0)

#define chmax(x, v) x = max(x, (v))
#define chmin(x, v) x = min(x, (v))
#define fi first
#define se second

const long long BIG = 10000000000000000LL;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

void solve();
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	solve();
	return 0;
}

const int borne = 201*1000;
int nbAntennes, nbRequetes;

struct Antenne
{
	int hauteur, rgDeb, rgFin;
};

struct Requete
{
	int deb=0, fin=0, rep=-1;
};

vector<Antenne> ants;
vector<Requete> requetes;


// Segtree

int stOrig[4*borne];
int stCool[4*borne]; // Une nomenclature de qualité
int lazy[4*borne];

void pushCool(int nod) // A VERIFIER
{
	if (lazy[nod] != BIG) {
		chmax(stCool[nod], stOrig[nod] - lazy[nod]);
		//cout << nod << " " << stOrig[nod] << " " << lazy[nod] << " => " << stOrig[nod] - lazy[nod] << "\n";
	}

	if (2*nod+1 < 4*borne) {
		chmin(lazy[2*nod], lazy[nod]);
		chmin(lazy[2*nod+1], lazy[nod]);
	}

	lazy[nod] = BIG;
}

void updOrig(int nod, int lno, int rno, int pos, int val)
{
	pushCool(nod); // A VERIFIER
	if (lno == rno) {
		assert(lno == pos);
		stOrig[nod] = val;
	} else {
		int midNo = (lno+rno) / 2;
		if (pos <= midNo) updOrig(2*nod, lno, midNo, pos, val);
		else updOrig(2*nod + 1, midNo+1, rno, pos, val);
		stOrig[nod] = max(stOrig[2*nod], stOrig[2*nod+1]);
	}
}

int getMaxCool(int nod, int lno, int rno, int li, int ri)
{
	pushCool(nod);
	if (lno > ri || rno < li) return -BIG;
	if (li <= lno && rno <= ri) return stCool[nod];
	int midNo = (lno+rno) / 2;

	int rd = max(getMaxCool(2*nod, lno, midNo, li, ri), getMaxCool(2*nod+1, midNo+1, rno, li, ri));
	return rd;
}

void updCool(int nod, int lno, int rno, int li, int ri, int delta)
{
	if (lno > ri || rno < li) return;
	if (li <= lno && rno <= ri) {
		chmin(lazy[nod], delta);
		pushCool(nod);
		return;
	}
	pushCool(nod);
	int midNo = (lno+rno) / 2;
	updCool(2*nod, lno, midNo, li, ri, delta);
	updCool(2*nod+1, midNo+1, rno, li, ri, delta);
	stCool[nod] = max(stCool[nod], max(stCool[2*nod], stCool[2*nod+1])); // A VERIFIER
}

// Fin segtree

vector<int> evAdd[borne];
vector<int> evDel[borne];
vector<int> evReq[borne];

void resoudre()
{
	fill_n(&stOrig[0], 4*borne, -BIG);
	fill_n(&stCool[0], 4*borne, -BIG);
	fill_n(&lazy[0], 4*borne, BIG);

	form(i, borne) { evAdd[i].clear(); evDel[i].clear(); evReq[i].clear(); }

	form(iReq, nbRequetes) {
		evReq[requetes[iReq].fin].push_back(iReq);
	}

	form(posAnt, nbAntennes) {
		Antenne &an = ants[posAnt];
		int posDeb = posAnt + an.rgDeb;
		if (posDeb >= nbAntennes) continue;
		int posFin = min(nbAntennes, posAnt + an.rgFin);

		evAdd[posDeb].push_back(posAnt);
		evDel[posFin].push_back(posAnt);
	}

	multiset<int> curHa;

	form(posAnt, nbAntennes) {

		for (int ev : evAdd[posAnt]) {
			updOrig(1, 0, nbAntennes-1, ev, ants[ev].hauteur);
		}

		Antenne &an = ants[posAnt];
		int rgDeb = max(0LL, posAnt - an.rgFin);
		int rgFin = posAnt - an.rgDeb;
		if (rgFin >= rgDeb) {
			updCool(1, 0, nbAntennes-1, rgDeb, rgFin, an.hauteur);
		}

		for (int ev : evReq[posAnt]) { // A VERIFIER : sur de l'ordre ?
			Requete &rq = requetes[ev];
			assert(rq.fin == posAnt);
			chmax(rq.rep, getMaxCool(1, 0, nbAntennes-1, rq.deb, rq.fin));
		}

		for (int ev : evDel[posAnt]) {
			updOrig(1, 0, nbAntennes-1, ev, -BIG);
		}
	}
}

void solve()
{
	cin >> nbAntennes;
	ants.resize(nbAntennes);

	form(iAnt, nbAntennes) {
		Antenne &an = ants[iAnt];
		cin >> an.hauteur >> an.rgDeb >> an.rgFin;
	}

	cin >> nbRequetes;
	requetes.resize(nbRequetes);

	form(iReq, nbRequetes) {
		cin >> requetes[iReq].deb >> requetes[iReq].fin;
		--requetes[iReq].deb;
		--requetes[iReq].fin;
		requetes[iReq].rep = -1;
	}

	resoudre();
	
	reverse(ants.begin(), ants.end());

	form(iReq, nbRequetes) {
		int newDeb = (nbAntennes - 1) - requetes[iReq].fin;
		int newFin = (nbAntennes - 1) - requetes[iReq].deb;
		
		requetes[iReq].deb = newDeb;
		requetes[iReq].fin = newFin;
	}

	resoudre();

	form(iReq, nbRequetes) cout << requetes[iReq].rep << "\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...