社区讨论
求助,CF上WA on test7
CF916EJamie and Tree参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhjdqlj6
- 此快照首次捕获于
- 2025/11/04 00:54 4 个月前
- 此快照最后确认于
- 2025/11/04 00:54 4 个月前
CPP
#include <bits/stdc++.h>
#define ls z[k].son[L]
#define rs z[k].son[R]
using namespace std;
typedef long long ll;
const int L = 0, R = 1;
const int N = 1e5 + 10;
int n, m, rot, root, cnt, tim;
int siz[N], dep[N], top[N], pos[N], dfn[N], a[N], f[N][25], son[N];
vector<int> G[N];
struct node{
ll sum, addtag;
int son[2];
}z[N << 2];
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-') f = -1;
ch = getchar();
}
while(ch <= '9' && ch >= '0'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void update(int k){
z[k].sum = z[ls].sum + z[rs].sum;
}
void build(int &k, int l, int r){
k = ++cnt;
if(l == r){
z[k].sum = 1ll * a[pos[l]];
return ;
}
int mid = l + r >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
update(k);
}
void add_tag(int k, int l, int r, int d){
z[k].addtag += 1ll * d;
z[k].sum += 1ll * (r - l + 1) * d;
}
void push_down(int k, int l, int r){
if(z[k].addtag != 0){
int mid = l + r >> 1;
add_tag(ls, l, mid, z[k].addtag);
add_tag(rs, mid + 1, r, z[k].addtag);
z[k].addtag = 0;
}
}
void modify(int k, int l, int r, int ql, int qr, int d){
if(ql <= l && qr >= r){
add_tag(k, l, r, d);
return ;
}
push_down(k, l, r);
int mid = l + r >> 1;
if(ql <= mid) modify(ls, l, mid, ql, qr, d);
if(qr > mid) modify(rs, mid + 1, r, ql, qr, d);
update(k);
}
ll query(int k, int l, int r, int ql, int qr){
if(ql <= l && qr >= r)
return z[k].sum;
push_down(k, l, r);
int mid = l + r >> 1;
ll ret = 0;
if(ql <= mid) ret += query(ls, l, mid, ql, qr);
if(qr > mid) ret += query(rs, mid + 1, r, ql, qr);
return ret;
}
void dfs1(int u, int fa){
dep[u] = dep[fa] + 1;
siz[u] = 1;
f[u][0] = fa;
for(int i = 1; i <= 23; ++i)
f[u][i] = f[f[u][i - 1]][i - 1];
for(auto v : G[u]){
if(v == fa) continue;
dfs1(v, u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs2(int u, int tp){
top[u] = tp;
dfn[u] = ++tim;
pos[tim] = u;
if(son[u]) dfs2(son[u], tp);
for(auto v : G[u]){
if(v == f[u][0] || v == son[u]) continue;
dfs2(v, v);
}
}
int lca(int x, int y){
while(top[x] != top[y]){
if(dep[top[x]] < dep[top[y]])
swap(x, y);
x = f[top[x]][0];
}
return dep[x] < dep[y] ? x : y;
}
int get_son(int x, int y){
if(dep[x] < dep[y])
swap(x, y);
for(int i = 23; i >= 0; --i)
if(dep[f[x][i]] > dep[y])
x = f[x][i];
return x;
}
void get_modify(int x, int y, int w){
int l = lca(x, y), r = lca(x, root), z = lca(y, root);
if(dep[r] > dep[l])
l = r;
if(dep[z] > dep[l])
l = z;
if(l == root) modify(rot, 1, n, 1, n, w);
else{
if(lca(l, root) == l){
modify(rot, 1, n, 1, n, w);
int s = get_son(l, root);
modify(rot, 1, n, dfn[s], dfn[s] + siz[s] - 1, -w);
}
else
modify(rot, 1, n, dfn[l], dfn[l] + siz[l] - 1, w);
}
}
void get_ans(int x){
if(x == root){
ll ans = query(rot, 1, n, 1, n);
cout << ans << '\n';
return ;
}
else{
if(lca(x, root) == x){
ll ans = query(rot, 1, n, 1, n);
int s = get_son(x, root);
ans -= query(rot, 1, n, dfn[s], dfn[s] + siz[s] - 1);
cout << ans << '\n';
return ;
}
else{
ll ans = query(rot, 1, n, dfn[x], dfn[x] + siz[x] - 1);
cout << ans << '\n';
return ;
}
}
}
int main(){
n = read(), m = read();
for(int i = 1; i <= n; ++i)
a[i] = read();
for(int i = 1; i < n; ++i){
int u, v;
u = read(), v = read();
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
build(rot, 1, n);
while(m--){
int op, l, r, x;
op = read();
if(op == 1)
root = read();
else if(op == 2){
l = read(), r = read(), x = read();
get_modify(l, r, x);
}
else{
x = read();
get_ans(x);
}
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...