社区讨论
求卡常,95pts TLE on #6
P4775[NOI2018] 情报中心参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @m34h9yu3
- 此快照首次捕获于
- 2024/11/05 21:20 去年
- 此快照最后确认于
- 2025/11/04 15:16 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
bool debug = false, debug2 = false;
#define int long long
inline int read()
{
int x=0,f=1;
char ch;
while(ch>'9'||ch<'0')
{
if(ch=='-')f=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0)putchar('-'),x=-x;
if(x>=10)write(x/10);
putchar(x%10+'0');
}
const int N = 5e4 + 5, M = 2e5 + 5;
const int SZ = 1e7;
const int inf = 0x3f3f3f3f3f3f3f3f;
int n, m;
struct Edge {
int to, val;
Edge(int t = 0, int v = 0) {
to = t, val = v;
}
};
vector<Edge> e[N];
int dfn[N], cur = 0;
int st[20][N], pw[20], lg[N] = {};
int d[N], dep[N] = {};
int fa[16][N];
void dfs(int x, int pr, int dth) {
dep[x] = dep[pr] + 1;
dfn[x] = ++cur;
d[x] = dth;
st[0][dfn[x]] = pr;
fa[0][x] = pr;
for (int i = 1; i < 16; i++)
fa[i][x] = fa[i - 1][fa[i - 1][x]];
for (auto i: e[x])
if (i.to != pr)
dfs(i.to, x, dth + i.val);
}
int sml(int x, int y) {
if (dfn[x] < dfn[y])
return x;
return y;
}
void init_ST() {
pw[0] = 1;
for (int i = 1; i < 20; i++)
pw[i] = pw[i - 1] * 2;
for (int i = 2; i <= n; i++)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i < 20; i++)
for (int j = 1; j + pw[i] - 1 <= n; j++)
st[i][j] = sml(st[i - 1][j], st[i - 1][j + pw[i - 1]]);
}
inline int lca(int x, int y) {
if (x == y)
return x;
x = dfn[x], y = dfn[y];
if (x > y)
swap(x, y);
int s = lg[y - x];
return sml(st[s][x + 1], st[s][y - pw[s] + 1]);
}
inline int up(int x, int t) {
for (int i = 15; i >= 0; i--)
if (dep[fa[i][x]] > dep[t])
x = fa[i][x];
return x;
}
inline int dist(int x, int y) {
int lc = lca(x, y);
return d[x] + d[y] - 2 * d[lc];
}
struct Path {
int u, v, w;
int C;
void getC() {
C = dist(u, v) - 2 * w;
}
} p[M];
typedef pair<int, int> pii;
int cst[M];
inline int len(int id1, int id2) {
if (id1 == -1 || id2 == -1)
return ~inf;
int v1 = p[id1].v, v2 = p[id2].v;
return cst[id1] + cst[id2] + dist(v1, v2);
}
inline int len(pii x) {
return len(x.first, x.second);
}
inline bool chk(int id1, int id2) {
return min(id1, id2) + m != max(id1, id2);
}
inline pii operator+(pii a, pii b) {
pii ret = a;
if ((ret.first == -1 && ret.second == -1) || len(ret) < len(b))
ret = b;
if (chk(a.first, b.first) && len(ret) < len(a.first, b.first))
ret = make_pair(a.first, b.first);
if (chk(a.first, b.second) && len(ret) < len(a.first, b.second))
ret = make_pair(a.first, b.second);
if (chk(a.second, b.first) && len(ret) < len(a.second, b.first))
ret = make_pair(a.second, b.first);
if (chk(a.second, b.second) && len(ret) < len(a.second, b.second))
ret = make_pair(a.second, b.second);
return ret;
}
inline pii operator*(pii a, pii b) {
pii ret = make_pair(-1, -1);
if (chk(a.first, b.first) && len(ret) < len(a.first, b.first))
ret = make_pair(a.first, b.first);
if (chk(a.first, b.second) && len(ret) < len(a.first, b.second))
ret = make_pair(a.first, b.second);
if (chk(a.second, b.first) && len(ret) < len(a.second, b.first))
ret = make_pair(a.second, b.first);
if (chk(a.second, b.second) && len(ret) < len(a.second, b.second))
ret = make_pair(a.second, b.second);
return ret;
}
struct SegmentTree {
int n;
int rt[N];
int ls[SZ], rs[SZ];
pii val[SZ]; //保存两条最优路径的编号
void pushup(int x) {
if (!ls[x] || !rs[x])
val[x] = val[ls[x] + rs[x]];
else
val[x] = val[ls[x]] + val[rs[x]];
}
void mdf(int &x, int lx, int rx, int p, int v) {
if (x == 0) {
x = ++n;
ls[x] = rs[x] = 0;
val[x] = make_pair(-1, -1);
}
if (lx + 1 == rx) {
if (v == -1)
val[x] = make_pair(-1, -1);
else
val[x] = make_pair(lx, -1);
// if (debug)
// printf("%d:%d %d\n", x, val[x].first, val[x].second);
return ;
}
int m = (lx + rx) / 2;
if (p < m)
mdf(ls[x], lx, m, p, v);
else
mdf(rs[x], m, rx, p, v);
pushup(x);
// if (debug) {
// printf("%d:%d %d\n", x, val[x].first, val[x].second);
// printf("%d, %d %d\n", x, ls[x], rs[x]);
// }
}
int mrg(int L, int R, int lx, int rx) {
if (L == 0 || R == 0)
return L + R;
if (lx + 1 == rx) {
val[L] = val[L] + val[R];
return L;
}
int m = (lx + rx) / 2;
ls[L] = mrg(ls[L], ls[R], lx, m);
rs[L] = mrg(rs[L], rs[R], m, rx);
pushup(L);
return L;
}
} sgt;
vector<int> tag[N];
int ans;
inline void clear_vec(vector<int> &v) {
vector<int> tmp;
swap(v, tmp);
}
void clear_all() {
ans = -inf;
for (int i = 1; i <= sgt.n; i++) {
sgt.val[i] = make_pair(-1, -1);
sgt.ls[i] = sgt.rs[i] = 0;
}
sgt.val[0] = make_pair(-1, -1);
sgt.n = 0;
for (int i = 1; i <= n; i++) {
sgt.rt[i] = 0;
clear_vec(tag[i]);
e[i].clear();
}
cur = 0;
}
void srh(int x, int pr) {
if (sgt.val[sgt.rt[x]].first != -1 && sgt.val[sgt.rt[x]].second != -1)
ans = max(ans, len(sgt.val[sgt.rt[x]]) - 2 * d[x]);
for (auto i: e[x]) {
if (i.to == pr)
continue;
srh(i.to, x);
pii tmp = sgt.val[sgt.rt[x]] * sgt.val[sgt.rt[i.to]];
if (tmp.first != -1 && tmp.second != -1)
ans = max(ans, len(tmp) - 2 * d[x]);
sgt.rt[x] = sgt.mrg(sgt.rt[x], sgt.rt[i.to], 1, 2 * m + 1);
}
for (auto i: tag[x]) {
sgt.mdf(sgt.rt[x], 1, 2 * m + 1, i, -1);
}
}
void slv() {
n = read();
clear_all();
for (int i = 1, u, v, w; i < n; i++) {
u = read();
v = read();
w = read();
e[u].push_back(Edge(v, w));
e[v].push_back(Edge(u, w));
}
dfs(1, 0, 0);
init_ST();
m = read();
for (int i = 1; i <= m; i++) {
p[i].u = read();
p[i].v = read();
p[i].w = read();
if (p[i].u == p[i].v)
continue;
p[m + i] = p[i];
swap(p[m + i].u, p[m + i].v);
p[i].getC();
p[m + i].getC();
cst[i] = p[i].C + d[p[i].u];
cst[m + i] = p[m + i].C + d[p[m + i].u];
if (lca(p[i].u, p[i].v) != p[i].u) {
sgt.mdf(sgt.rt[p[i].u], 1, 2 * m + 1, i, 1);
tag[up(p[i].u, lca(p[i].u, p[i].v))].push_back(i);
}
if (lca(p[m + i].u, p[m + i].v) != p[m + i].u) {
sgt.mdf(sgt.rt[p[m + i].u], 1, 2 * m + 1, m + i, 1);
tag[up(p[m + i].u, lca(p[m + i].u, p[m + i].v))].push_back(m + i);
}
}
srh(1, 0);
if (ans == -inf) {
putchar('F');
putchar('\n');
}
else {
write(ans / 2);
putchar('\n');
}
}
signed main() {
int T;
cin >> T;
for (int i = 1; i <= T; i++) {
slv();
}
return 0;
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...