世界线
世界线
http://www.nowcoder.com/questionTerminal/10ca2f702456464bb060a4d23bc1d628
这 ** 的什么毒瘤出的题,还告诉我int范围,痛失rk1
行呗,这题就是经典套路,反正我不会树高非的优秀做法,就说说垃圾做法好了/cy
你考虑到你的 u -> v , 那么对 ()的深度是要减掉 的,对其他区间是要加上的,那么很显然,他说了深度是 的,那么一个点在子树内只会被覆盖 次,每次暴力覆盖,复杂度是 ,查询在线段树上二分就可以了。
ps:这玩意不能模拟减掉 ,只能加上个 ,然后动态开点线段树瞎搞搞就过了/cy
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #pragma GCC optimize( \ "inline,-fgcse,-fgcse-lm,-fipa-sra,-ftree-pre,-ftree-vrp,-fpeephole2,-ffast-math,-fsched-spec,unroll-loops,-falign-jumps,-falign-loops,-falign-labels,-fdevirtualize,-fcaller-saves,-fcrossjumping,-fthread-jumps,-funroll-loops,-freorder-blocks,-fschedule-insns,inline-functions,-ftree-tail-merge,-fschedule-insns2,-fstrict-aliasing,-fstrict-overflow,-falign-functions,-fcse-follow-jumps,-fsched-interblock,-fpartial-inlining,no-stack-protector,-freorder-functions,-findirect-inlining,-fhoist-adjacent-loads,-frerun-cse-after-loop,inline-small-functions,-finline-small-functions,-ftree-switch-conversion,-foptimize-sibling-calls,-fexpensive-optimizations,inline-functions-called-once,-fdelete-null-pointer-checks") #include <bits/stdc++.h> #define int long long using namespace std; const int SZ = 1 << 23 | 233; struct FILEIN { char qwq[SZ], *S = qwq, *T = qwq, ch; #ifdef __WIN64 #define GETC getchar #else char GETC() { return (S == T) && (T = (S = qwq) + fread(qwq, 1, SZ, stdin), S == T) ? EOF : *S++; } #endif FILEIN& operator>>(char& c) { while (isspace(c = GETC())) ; return *this; } FILEIN& operator>>(string& s) { while (isspace(ch = GETC())) ; s = ch; while (!isspace(ch = GETC())) s += ch; return *this; } template <class T> void read(T& x) { bool sign = 0; while ((ch = GETC()) < 48) sign ^= (ch == 45); x = (ch ^ 48); while ((ch = GETC()) > 47) x = (x << 1) + (x << 3) + (ch ^ 48); x = sign ? -x : x; } FILEIN& operator>>(int& x) { return read(x), *this; } } in; struct FILEOUT { const static int LIMIT = 1 << 22; char quq[SZ], ST[233]; int sz, O; ~FILEOUT() { flush(); } void flush() { fwrite(quq, 1, O, stdout); fflush(stdout); O = 0; } FILEOUT& operator<<(char c) { return quq[O++] = c, *this; } FILEOUT& operator<<(string str) { if (O > LIMIT) flush(); for (char c : str) quq[O++] = c; return *this; } template <class T> void write(T x) { if (O > LIMIT) flush(); if (x < 0) { quq[O++] = 45; x = -x; } do { ST[++sz] = x % 10 ^ 48; x /= 10; } while (x); while (sz) quq[O++] = ST[sz--]; } FILEOUT& operator<<(int x) { return write(x), *this; } } out; int n, m, q; const int maxn = 1e5 + 51; const int QAQ = 4e15; const int QWQ = 1e15; struct Edge { int v, nxt, w; } e[maxn << 1]; int head[maxn], ecnt = 0; void add(int u, int v, int w) { e[++ecnt] = { v, head[u], w }; head[u] = ecnt; } int a[maxn], dfn[maxn], tot = 0; int sz[maxn], fa[maxn], dep[maxn]; vector<pair<int, int>> qr[maxn]; int ans[maxn]; int ls[maxn << 8], rs[maxn << 8], val[maxn << 8]; int cnt = 0; void upd(int l, int r, int& p, int x, int v) { if (!p) p = ++cnt; val[p] += v; if (l == r) return; int mid = l + r >> 1; if (x <= mid) upd(l, mid, ls[p], x, v); else upd(mid + 1, r, rs[p], x, v); } int qry(int l, int r, int p, int k) { if (l == r) return l; int mid = l + r >> 1; if (k > val[ls[p]]) return qry(mid + 1, r, rs[p], k - val[ls[p]]); else return qry(l, mid, ls[p], k); } void dfs(int u) { a[dfn[u] = ++tot] = dep[u]; sz[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if (v == fa[u]) continue; dep[v] = dep[u] + e[i].w, fa[v] = u, dfs(v); sz[u] += sz[v]; } } int rt = 0; void dfssolve(int u) { upd(1, QAQ, rt, a[dfn[u]] + QWQ, -1); for (auto x : qr[u]) ans[x.second] = qry(1, QAQ, rt, tot - x.first) + dep[u] - QWQ; upd(1, QAQ, rt, a[dfn[u]] + QWQ, 1); for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if (v == fa[u]) continue; for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) upd(1, QAQ, rt, a[j] + QWQ, -1); for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) a[j] -= e[i].w * 2; for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) upd(1, QAQ, rt, a[j] + QWQ, 1); dfssolve(v); for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) upd(1, QAQ, rt, a[j] + QWQ, -1); for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) a[j] += e[i].w * 2; for (int j = dfn[v]; j <= dfn[v] + sz[v] - 1; j++) upd(1, QAQ, rt, a[j] + QWQ, 1); } } signed main() { in >> n >> m >> q; while (m--) { int u, v, w; in >> u >> v >> w; add(u, v, w); add(v, u, w); } for (int i = 1; i <= q; i++) { int x, k; in >> x >> k; qr[x].push_back({ k, i }); } for (int i = 1; i <= n; i++) if (!dfn[i]) { for (int j = 1; j <= cnt; j++) val[j] = ls[j] = rs[j] = 0; rt = cnt = dep[i] = tot = 0; dfs(i); for (int j = 1; j <= tot; j++) upd(1, QAQ, rt, a[j] + QWQ, 1); dfssolve(i); } for (int i = 1; i <= q; i++) out << (ans[i] <= 0 ? -1 : ans[i]) << '\n'; return 0; }