社区讨论
MLE 求助qwq
P2590[ZJOI2008] 树的统计参与者 4已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mi865a4s
- 此快照首次捕获于
- 2025/11/21 09:15 4 个月前
- 此快照最后确认于
- 2025/11/21 09:15 4 个月前
CPP
#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a))
#define For(i, k, j) for(int i = (k); i <= (j); i++)
#define INF 2147483647
#define eps 1e-4
using namespace std;
inline int read()
{
int num = 0; char c=' '; int flag = 1;
for(;c>'9'||c<'0';c=getchar()) if(c=='-') flag = -1;
for(;c>='0'&&c<='9';num=(num<<1)+(num<<3)+c-48,c=getchar());
return num * flag;
}
int n, Qnum;
#define MAXN 100005
struct Edge {
int v, nxt;
}e[MAXN << 1];
int lst[MAXN], tot = 0;
inline void addedge(int u, int v) {
e[++tot] = (Edge) {v, lst[u]};
lst[u] = tot;
}
int fa[MAXN], siz[MAXN], dep[MAXN];
int fir[MAXN], pos[MAXN], Num = 0;
void dfs1(int u, int Fa) {
fa[u] = Fa, siz[u] = 1;
for(int i = lst[u]; i; i = e[i].nxt) {
int v = e[i].v; if(v == Fa) return;
dep[v] = dep[u] + 1;
dfs1(v, u);
siz[u] += siz[v];
}
}
void dfs2(int u, int chain) {
fir[u] = chain, pos[u] = ++Num;
int maxi = -1, maxv = -1;
for(int i = lst[u]; i; i = e[i].nxt) {
int v = e[i].v; if(v == fa[u]) continue;
if(siz[v] > maxv)
maxv = siz[v], maxi = v;
}
if(maxi == -1) return;
dfs2(maxi, chain);
for(int i = lst[u]; i; i = e[i].nxt) {
int v = e[i].v;
if(v != fa[u] && v != maxi)
dfs2(v, v);
}
return;
}
int sum[MAXN << 2], maxi[MAXN << 2];
#define ls (k << 1)
#define rs (k << 1 | 1)
#define mid ((l + r) >> 1)
void pushup(int k) {
sum[k] = sum[ls] + sum[rs];
maxi[k] = max(maxi[ls], maxi[rs]);
}
void update(int k, int l, int r, int pos, int val) {
if(l == pos && r == pos) {sum[k] = maxi[k] = val; return;}
if(pos <= mid) update(ls, l, mid, pos, val);
else update(rs, mid+1, r, pos, val);
pushup(k);
}
int querymax(int k, int l, int r, int ql, int qr) {
// cout << l << ' ' << r << ' ' << mid << ' ' << ql << ' ' << qr << endl;
// For(i, 1, 500000000);
if(l == ql && r == qr)return maxi[k];
if(qr <= mid) return querymax(ls, l, mid, ql, qr);
else if(ql > mid) return querymax(rs, mid+1, r, ql, qr);
else return max(querymax(ls, l, mid, ql, mid), querymax(rs, mid+1, r, mid+1, qr));
}
int querysum(int k, int l, int r, int ql, int qr) {
if(l == ql && r == qr)return sum[k];
if(qr <= mid) return querysum(ls, l, mid, ql, qr);
else if(ql > mid) return querysum(rs, mid+1, r, ql, qr);
else return querysum(ls, l, mid, ql, mid) + querysum(rs, mid+1, r, mid+1, qr);
}
int Getmax(int x, int y) {
int ans = - (1 << 30);
while(fir[x] != fir[y]) {
// cout << "*" <<' ' << x << ' ' << y << endl;
if(dep[fir[x]] < dep[fir[y]]) swap(x, y);
ans = max(ans, querymax(1, 1, n, pos[fir[x]], pos[x]));
x = fa[fir[x]];
}
if(pos[x] > pos[y]) swap(x, y);
ans = max(ans, querymax(1, 1, n, pos[x], pos[y]));
return ans;
}
int Getsum(int x, int y) {
int ans = 0;
while(fir[x] != fir[y]) {
if(dep[fir[x]] < dep[fir[y]]) swap(x, y);
ans += querysum(1, 1, n, pos[fir[x]], pos[x]);
x = fa[fir[x]];
}
if(pos[x] > pos[y]) swap(x, y);
ans += querysum(1, 1, n, pos[x], pos[y]);
return ans;
}
signed main()
{
n = read();
for(int i = 1; i < n; i++) {
int u = read(), v = read();
addedge(u, v); addedge(v, u);
}
memset(sum, 0, sizeof(sum));
memset(maxi, -126, sizeof(maxi));
memset(dep, 0, sizeof(dep));
memset(fa, 0, sizeof(fa));
memset(fir, 0, sizeof(fir));
memset(siz, 0, sizeof(siz));
memset(pos, 0, sizeof(pos));
Num = 0, dep[0] = -1;
dfs1(1, 0);
dfs2(1, 1);
for(int i = 1; i <= n; i++) {
int val; scanf("%d", &val);
update(1, 1, n, pos[i], val);
}
int Qnum = read();
while(Qnum--) {
char opt[10]; int a, b;
scanf("%s %d %d", opt, &a, &b);
if(opt[1] == 'H') {
update(1, 1, n, pos[a], b);
} else if(opt[1] == 'M') {
printf("%d\n", Getmax(a, b));
} else {
printf("%d\n", Getsum(a, b));
}
}
return 0;
}
/*
*/```
回复
共 7 条回复,欢迎继续交流。
正在加载回复...