世界线

世界线

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;
}
全部评论

相关推荐

最近又搬回宿舍了,在工位坐不住,写一写秋招起伏不断的心态变化,也算对自己心态的一些思考表演式学习从开始为实习准备的时候就特别焦虑,楼主一开始选择的是cpp后端,但是24届这个方向已经炸了,同时自己又因为本科非92且非科班,所以感到机会更加迷茫。在某天晚上用java写出hello&nbsp;world并失眠一整晚后选择老本行干嵌入式。理想是美好的,现实情况是每天忙但又没有实质性进展,总是在配环境,调工具,顺带还要推科研。而这时候才发现自己一直在表演式学习,徘徊在设想如何展开工作的循环里,导致没有实质性进展。现在看来当时如果把精力专注在动手写而不是两只手端着看教程,基本功或许不会那么差。实习的焦虑5月,楼主...
耶比:哲学上有一个问题,玛丽的房间:玛丽知道眼睛识别色彩的原理知道各种颜色,但是她生活在黑白的房间里,直到有一天玛丽的房门打开了她亲眼看到了颜色,才知道什么是色彩。我现在最大可能的减少对非工作事情的思考,如果有一件事困扰了我, 能解决的我就直接做(去哪里或者和谁吵架等等……),解决不了的我就不想了,每一天都是最年轻的一天,珍惜今天吧
投递比亚迪等公司10个岗位 > 秋招被确诊为…… 牛客创作赏金赛
点赞 评论 收藏
分享
10-28 14:42
门头沟学院 Java
watermelon1124:因为嵌入式炸了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务