Submission #74245

#TimeUsernameProblemLanguageResultExecution timeMemory
74245kingpig9Factories (JOI14_factories)C++11
18 / 100
8096 ms289292 KiB
#include <bits/stdc++.h> #include "factories.h" using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; //#define debug(...) fprintf(stderr, __VA_ARGS__) #define debug(...) #define fi first #define se second #define all(v) (v).begin(), (v).end() #define fillchar(a, s) memset((a), (s), sizeof(a)) const int MAXN = 5e5 + 10; const int MAXLG = 19; const ll INF = 1e16; void setmin (ll &a, ll b) { if (a > b) { a = b; } } int N; #warning DON'T CONFUSE CENTROID DECOMPOSITION TREE WITH ORIGINAL TREE!!!!!!! vector<int> adj[MAXN]; map<pii, ll> mpw; //0 = white, 1 = red, 2 = blue int par[MAXN][MAXLG]; int depth[MAXN]; //depth in terms of # of edges (ignoring the weights!) ll droot[MAXN]; //dist to root int ent[MAXN], exi[MAXN]; ll getw (int a, int b) { return mpw.at(minmax(a, b)); } void dfslca (int x, int p, int de, ll dr) { static int cur = 0; ent[x] = cur++; depth[x] = de; droot[x] = dr; par[x][0] = p; for (int i = 1; i < MAXLG; i++) { int pp = par[x][i - 1]; if (pp == -1) { break; } par[x][i] = par[pp][i - 1]; } for (int y : adj[x]) { if (y != p) { dfslca(y, x, de + 1, dr + getw(x, y)); } } exi[x] = cur; } int getpar (int x, int d) { for (int i = 0; d; i++, d >>= 1) { if (d & 1) { x = par[x][i]; } } return x; } int lca (int x, int y) { if (depth[x] < depth[y]) { swap(x, y); } x = getpar(x, depth[x] - depth[y]); if (x == y) { return x; } for (int i = MAXLG - 1; i >= 0; i--) { if (par[x][i] != par[y][i]) { x = par[x][i]; y = par[y][i]; } } return par[x][0]; } //might be a hint. ll dist (int x, int y, int c = -1) { if (c == -1) { c = lca(x, y); } return droot[x] + droot[y] - 2 * droot[c]; } void calc_lca() { fillchar(par, -1); dfslca(0, -1, 0, 0ll); } void Init (int nn, int a[], int b[], int d[]) { N = nn; for (int i = 0; i < N - 1; i++) { adj[a[i]].push_back(b[i]); adj[b[i]].push_back(a[i]); mpw[minmax(a[i], b[i])] = d[i]; } calc_lca(); } bool cmpo (int x, int y) { return ent[x] < ent[y]; } bool insub (int x, int y) { return ent[x] < ent[y] && exi[y] <= exi[x]; } int color[MAXN]; set<pll> cadj[MAXN]; vector<int> verts; int vertsind; ll ans; void dfsv() { int x = verts[vertsind++]; //debug("x = %d\n", x); while (vertsind < verts.size()) { int y = verts[vertsind]; if (insub(x, y)) { ll d = dist(x, y); debug("cadj %d %d, dist = %lld\n", x, y, d); cadj[x].insert(pll(y, d)); cadj[y].insert(pll(x, d)); dfsv(); } else { break; } } } int sub[MAXN]; int findsub (int x, int p) { sub[x] = 1; for (pll py : cadj[x]) { int y = py.fi; if (y != p) { sub[x] += findsub(y, x); } } debug("sub[%d] = %d\n", x, sub[x]); return sub[x]; } int findcent (int x) { int s = findsub(x, -1); debug("sz %d is %d\n", x, s); int p = -1, cur = x; while (true) { bool ok = true; for (pll py : cadj[x]) { int y = py.fi; if (y != p) { if (sub[y] * 2 >= s) { p = cur; cur = y; ok = false; break; } } } if (ok) { return cur; } } } void dfsub (int x, int p, ll dr, ll &near1, ll &near2) { if (color[x] == 1) { setmin(near1, dr); } else if (color[x] == 2) { setmin(near2, dr); } for (pll py : cadj[x]) { int y = py.fi; if (y != p) { dfsub(y, x, dr + py.se, near1, near2); } } } void dfsc (int x) { int ff = x; x = findcent(x); debug("x = %d, centx = %d\n", ff, x); ll cnear1 = INF, cnear2 = INF; for (pll py : cadj[x]) { int y = py.fi; ll near1 = INF, near2 = INF; debug("me\n"); dfsub(y, x, py.se, near1, near2); debug("g\n"); debug("near1 = %lld, near2 = %lld\n", near1, near2); debug("cnear1 = %lld, cnear2 = %lld\n", cnear1, cnear2); setmin(ans, near1 + cnear2); setmin(ans, near2 + cnear1); if (color[x] == 1) { setmin(ans, near2); } else if (color[x] == 2) { setmin(ans, near1); } //At the end setmin(cnear1, near1); setmin(cnear2, near2); } //delete the ones while (!cadj[x].empty()) { int y = cadj[x].begin()->fi; //assert(cadj[y].lower_bound(pll(x, -1)) != cadj[y].end()); debug("erase %d %d\n", x, y); cadj[y].erase(cadj[y].lower_bound(pll(x, -1))); cadj[x].erase(cadj[x].begin()); dfsc(y); } } ll Query (int S, int X[], int T, int Y[]) { for (int i = 0; i < S; i++) { color[X[i]] = 1; } for (int i = 0; i < T; i++) { color[Y[i]] = 2; } #warning DON'T RETURN UNTIL YOU RESET STUFF!!! for (int i = 0; i < S; i++) { verts.push_back(X[i]); } for (int i = 0; i < T; i++) { verts.push_back(Y[i]); } sort(all(verts), cmpo); for (int i = 0; i + 1 < S + T; i++) { verts.push_back(lca(verts[i], verts[i + 1])); } sort(all(verts), cmpo); verts.resize(unique(all(verts)) - verts.begin()); vertsind = 0; dfsv(); ans = INF; dfsc(verts[0]); //END verts.clear(); for (int i = 0; i < S; i++) { color[X[i]] = 0; } for (int i = 0; i < T; i++) { color[Y[i]] = 0; } debug("------RETURN ANS---------\n"); return ans; }

Compilation message (stderr)

factories.cpp:28:13: warning: missing terminating ' character
 #warning DON'T CONFUSE CENTROID DECOMPOSITION TREE WITH ORIGINAL TREE!!!!!!!
             ^
factories.cpp:28:2: warning: #warning DON'T CONFUSE CENTROID DECOMPOSITION TREE WITH ORIGINAL TREE!!!!!!! [-Wcpp]
 #warning DON'T CONFUSE CENTROID DECOMPOSITION TREE WITH ORIGINAL TREE!!!!!!!
  ^~~~~~~
factories.cpp:246:13: warning: missing terminating ' character
 #warning DON'T RETURN UNTIL YOU RESET STUFF!!!
             ^
factories.cpp:246:2: warning: #warning DON'T RETURN UNTIL YOU RESET STUFF!!! [-Wcpp]
 #warning DON'T RETURN UNTIL YOU RESET STUFF!!!
  ^~~~~~~
factories.cpp: In function 'void dfsv()':
factories.cpp:132:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  while (vertsind < verts.size()) {
         ~~~~~~~~~^~~~~~~~~~~~~~
factories.cpp: In function 'void dfsc(int)':
factories.cpp:200:6: warning: unused variable 'ff' [-Wunused-variable]
  int ff = x;
      ^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...