답안 #109682

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
109682 2019-05-07T12:49:10 Z hugo_pm Election Campaign (JOI15_election_campaign) C++17
100 / 100
728 ms 39264 KB
#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 = 1000000000000000000LL;

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;
}

// Version classique du segment tree
// Opérations en O(log N)
// Indices 0-indexés

class SegtreeClassic
{
    public:
        void init(vector<int> tab);
        int requete(int gauche, int droite);
        void modifier(int index, int val);

    private:
        const int UNDEF = BIG+10;
        int nbElements;
        int combiner(int a, int b);
        vector<int> interne;
};

void SegtreeClassic::init(vector<int> tab)
{
    nbElements = tab.size();
    interne.resize(2 * nbElements);

    for (int ind = 0; ind < nbElements; ++ind)
        interne[ind + nbElements] = tab[ind];

    for (int ind = nbElements - 1; ind >= 0; --ind)
        interne[ind] = combiner(interne[2*ind], interne[2*ind + 1]);
}

int SegtreeClassic::requete(int gauche, int droite)
{
    int res = UNDEF;
    ++droite; // Pour passer à un intervalle semi-ouvert [l ; r[
    gauche += nbElements;
    droite += nbElements;

    while (gauche < droite)
    {
        // Si gauche est impair, le noeud est inclus mais pas le parent
        // On ajoute donc ce noeud et on passera plus tard au noeud à droite du parent
        if (gauche & 1)
            res = combiner(res, interne[gauche++]);
        // Même raisonnement sachant que droite est exclus, d'où la {pré}-décrémentation
        if (droite & 1)
            res = combiner(res, interne[--droite]);
        
        gauche /= 2;
        droite /= 2;
    }

    return res;
}

void SegtreeClassic::modifier(int index, int val)
{
    index += nbElements;
    interne[index] = val;
    index /= 2;
    while (index > 0)
    {
        interne[index] = combiner(interne[2*index], interne[2*index+1]);
        index /= 2;
    }
}

int SegtreeClassic::combiner(int a, int b)
{
    if (a == UNDEF) return b;
    if (b == UNDEF) return a;
    return a + b;
}

const int borne = 100*1000 + 5;
const int lgb = 19;
int nbNoeuds, nbPlans;
vector<int> adj[borne];
int prof[borne], par[borne];
int anc[lgb][borne];

int deb[borne], fin[borne];
int curTemps = 0;

void dfsInit(int nod)
{
	deb[nod] = curTemps++;
	anc[0][nod] = par[nod];
	form2(i, 1, lgb) {
		int tmp = anc[i-1][nod];
		if (tmp == -1) anc[i][nod] = -1;
		else anc[i][nod] = anc[i-1][tmp];
	}
	for (int vo : adj[nod]) if (vo != par[nod]) {
		prof[vo] = prof[nod] + 1;
		par[vo] = nod;
		dfsInit(vo);
	}
	fin[nod] = curTemps++;
}

int lca(int u, int v)
{
	if (u == v) return u;
	if (prof[u] > prof[v]) swap(u,v); // v devient le plus profond
	ford(i, lgb) {
		int nv = anc[i][v];
		if (nv != -1 && prof[nv] >= prof[u]) {
			v = nv;
		}
	}
	assert(prof[v] == prof[u]);
	if (u == v) return u;
	
	ford(i, lgb) {
		int nu = anc[i][u];
		int nv = anc[i][v];
		if (nu != nv && nu != -1 && nv != -1) {
			u = nu; v = nv;
		}
	}
	assert(u != v);
	assert(par[u] == par[v]);
	return par[u];
}

SegtreeClassic sc;
int somEnf[borne], dp[borne];
typedef pair<pii, int> trio;
vector<trio> splitPlan[borne];

void dfsCalc(int nod)
{
	for (int vo : adj[nod]) if (vo != par[nod]) {
		dfsCalc(vo);
		somEnf[nod] += dp[vo];
	}
	
	dp[nod] = somEnf[nod];

	for (auto plan : splitPlan[nod]) {
		int pushFirst = sc.requete(0, deb[plan.fi.fi]);
		int pushSecond = sc.requete(0, deb[plan.fi.se]);
		chmax(dp[nod], plan.se + pushFirst + pushSecond + somEnf[nod]);
	}

	int valPush = somEnf[nod] - dp[nod];
	sc.modifier(deb[nod], valPush);
	sc.modifier(fin[nod], -valPush);
}

void solve()
{
	cin >> nbNoeuds;
	par[0] = -1;
	form(i, nbNoeuds-1) {
		int u, v; cin >> u >> v;
		--u; --v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfsInit(0);
	assert(curTemps == 2*nbNoeuds);
	sc.init(vector<int>(2*nbNoeuds, 0)); 

	cin >> nbPlans;
	form(i, nbPlans) {
		int u, v, rcp; cin >> u >> v >> rcp;
		--u; --v;
		splitPlan[lca(u,v)].push_back({{u,v}, rcp});
	}

	dfsCalc(0);
	cout << dp[0] << "\n";
}
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5120 KB Output is correct
2 Correct 7 ms 5220 KB Output is correct
3 Correct 7 ms 5324 KB Output is correct
4 Correct 7 ms 5376 KB Output is correct
5 Correct 236 ms 31680 KB Output is correct
6 Correct 102 ms 35652 KB Output is correct
7 Correct 235 ms 34396 KB Output is correct
8 Correct 194 ms 31736 KB Output is correct
9 Correct 240 ms 33392 KB Output is correct
10 Correct 198 ms 31740 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5120 KB Output is correct
2 Correct 6 ms 5120 KB Output is correct
3 Correct 11 ms 5632 KB Output is correct
4 Correct 380 ms 39128 KB Output is correct
5 Correct 293 ms 39076 KB Output is correct
6 Correct 302 ms 39264 KB Output is correct
7 Correct 269 ms 39128 KB Output is correct
8 Correct 345 ms 39176 KB Output is correct
9 Correct 328 ms 39180 KB Output is correct
10 Correct 335 ms 39132 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5120 KB Output is correct
2 Correct 6 ms 5120 KB Output is correct
3 Correct 11 ms 5632 KB Output is correct
4 Correct 380 ms 39128 KB Output is correct
5 Correct 293 ms 39076 KB Output is correct
6 Correct 302 ms 39264 KB Output is correct
7 Correct 269 ms 39128 KB Output is correct
8 Correct 345 ms 39176 KB Output is correct
9 Correct 328 ms 39180 KB Output is correct
10 Correct 335 ms 39132 KB Output is correct
11 Correct 22 ms 6400 KB Output is correct
12 Correct 382 ms 39180 KB Output is correct
13 Correct 358 ms 39148 KB Output is correct
14 Correct 321 ms 39128 KB Output is correct
15 Correct 370 ms 39228 KB Output is correct
16 Correct 403 ms 39112 KB Output is correct
17 Correct 361 ms 39100 KB Output is correct
18 Correct 369 ms 39208 KB Output is correct
19 Correct 302 ms 39204 KB Output is correct
20 Correct 328 ms 39256 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 490 ms 35160 KB Output is correct
2 Correct 392 ms 39252 KB Output is correct
3 Correct 728 ms 37736 KB Output is correct
4 Correct 347 ms 35140 KB Output is correct
5 Correct 601 ms 37280 KB Output is correct
6 Correct 319 ms 35292 KB Output is correct
7 Correct 669 ms 36960 KB Output is correct
8 Correct 392 ms 34624 KB Output is correct
9 Correct 378 ms 39244 KB Output is correct
10 Correct 708 ms 36484 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5120 KB Output is correct
2 Correct 7 ms 5220 KB Output is correct
3 Correct 7 ms 5324 KB Output is correct
4 Correct 7 ms 5376 KB Output is correct
5 Correct 236 ms 31680 KB Output is correct
6 Correct 102 ms 35652 KB Output is correct
7 Correct 235 ms 34396 KB Output is correct
8 Correct 194 ms 31736 KB Output is correct
9 Correct 240 ms 33392 KB Output is correct
10 Correct 198 ms 31740 KB Output is correct
11 Correct 8 ms 5504 KB Output is correct
12 Correct 10 ms 5632 KB Output is correct
13 Correct 8 ms 5504 KB Output is correct
14 Correct 7 ms 5504 KB Output is correct
15 Correct 8 ms 5632 KB Output is correct
16 Correct 10 ms 5504 KB Output is correct
17 Correct 8 ms 5504 KB Output is correct
18 Correct 8 ms 5504 KB Output is correct
19 Correct 8 ms 5504 KB Output is correct
20 Correct 9 ms 5504 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 5120 KB Output is correct
2 Correct 7 ms 5220 KB Output is correct
3 Correct 7 ms 5324 KB Output is correct
4 Correct 7 ms 5376 KB Output is correct
5 Correct 236 ms 31680 KB Output is correct
6 Correct 102 ms 35652 KB Output is correct
7 Correct 235 ms 34396 KB Output is correct
8 Correct 194 ms 31736 KB Output is correct
9 Correct 240 ms 33392 KB Output is correct
10 Correct 198 ms 31740 KB Output is correct
11 Correct 6 ms 5120 KB Output is correct
12 Correct 6 ms 5120 KB Output is correct
13 Correct 11 ms 5632 KB Output is correct
14 Correct 380 ms 39128 KB Output is correct
15 Correct 293 ms 39076 KB Output is correct
16 Correct 302 ms 39264 KB Output is correct
17 Correct 269 ms 39128 KB Output is correct
18 Correct 345 ms 39176 KB Output is correct
19 Correct 328 ms 39180 KB Output is correct
20 Correct 335 ms 39132 KB Output is correct
21 Correct 22 ms 6400 KB Output is correct
22 Correct 382 ms 39180 KB Output is correct
23 Correct 358 ms 39148 KB Output is correct
24 Correct 321 ms 39128 KB Output is correct
25 Correct 370 ms 39228 KB Output is correct
26 Correct 403 ms 39112 KB Output is correct
27 Correct 361 ms 39100 KB Output is correct
28 Correct 369 ms 39208 KB Output is correct
29 Correct 302 ms 39204 KB Output is correct
30 Correct 328 ms 39256 KB Output is correct
31 Correct 490 ms 35160 KB Output is correct
32 Correct 392 ms 39252 KB Output is correct
33 Correct 728 ms 37736 KB Output is correct
34 Correct 347 ms 35140 KB Output is correct
35 Correct 601 ms 37280 KB Output is correct
36 Correct 319 ms 35292 KB Output is correct
37 Correct 669 ms 36960 KB Output is correct
38 Correct 392 ms 34624 KB Output is correct
39 Correct 378 ms 39244 KB Output is correct
40 Correct 708 ms 36484 KB Output is correct
41 Correct 8 ms 5504 KB Output is correct
42 Correct 10 ms 5632 KB Output is correct
43 Correct 8 ms 5504 KB Output is correct
44 Correct 7 ms 5504 KB Output is correct
45 Correct 8 ms 5632 KB Output is correct
46 Correct 10 ms 5504 KB Output is correct
47 Correct 8 ms 5504 KB Output is correct
48 Correct 8 ms 5504 KB Output is correct
49 Correct 8 ms 5504 KB Output is correct
50 Correct 9 ms 5504 KB Output is correct
51 Correct 461 ms 34624 KB Output is correct
52 Correct 344 ms 39192 KB Output is correct
53 Correct 675 ms 36708 KB Output is correct
54 Correct 330 ms 34188 KB Output is correct
55 Correct 402 ms 35116 KB Output is correct
56 Correct 319 ms 39132 KB Output is correct
57 Correct 684 ms 37148 KB Output is correct
58 Correct 304 ms 34652 KB Output is correct
59 Correct 428 ms 34916 KB Output is correct
60 Correct 591 ms 39232 KB Output is correct
61 Correct 626 ms 36952 KB Output is correct
62 Correct 318 ms 36192 KB Output is correct
63 Correct 431 ms 35672 KB Output is correct
64 Correct 379 ms 39232 KB Output is correct
65 Correct 653 ms 37556 KB Output is correct
66 Correct 371 ms 34268 KB Output is correct
67 Correct 420 ms 35572 KB Output is correct
68 Correct 330 ms 39084 KB Output is correct
69 Correct 650 ms 36300 KB Output is correct
70 Correct 315 ms 35036 KB Output is correct