社区讨论
调不过来,WA#5#6
P2590[ZJOI2008] 树的统计参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo1d5qsk
- 此快照首次捕获于
- 2023/10/22 19:06 2 年前
- 此快照最后确认于
- 2023/11/02 19:50 2 年前
CPP
#include <bits/stdc++.h>//喵内~
#define re register//喵内~
#define int long long
using namespace std;//喵内~
typedef long long ll;
typedef long double ld;
const int N = 3e4 + 5;//喵内~要填数字哟~
inline int read(){
int s = 0,f = 1;char c = getchar();
while (!isdigit(c)){if (c == '-')f = -1;c = getchar();}
while (isdigit(c)){s = (s<<3) + (s<<1) + (c ^ 48);c = getchar();}
return s * f;
}//喵内~
int head[N],cnt,timer,dfn[N],rnk[N],top[N],size[N],son[N],dep[N],val[N],fa[N],h[N];
int n,m;
struct node{
int v,next;
}tree[N << 1];
char s[10];
void add(int u,int v){
tree[++cnt].next = head[u];
tree[cnt].v = v;
head[u] = cnt;
}
struct TernaryTree{
struct node{
int maxn,sum;
}tree[N << 2];
void pushup(int rt){
tree[rt].sum = tree[rt<<1].sum + tree[rt << 1 | 1].sum;
tree[rt].maxn = max(tree[rt << 1].maxn,tree[rt << 1 | 1].maxn);
}
void build(int rt,int l,int r){
if (l == r){
tree[rt].maxn = tree[rt].sum = val[rnk[l]];
return ;
}
int mid = l + r >> 1;
build(rt << 1,l,mid);
build(rt << 1 | 1,mid+1,r);
pushup(rt);
}
void change(int rt,int l,int r,int op,int t){
if (l == r){
tree[rt].sum = tree[rt].maxn = t;
return ;
}
int mid = l + r >> 1;
if (op <= mid)
change(rt << 1,l,mid,op,t);
else change(rt << 1 | 1,mid + 1,r,op,t);
pushup(rt);
}
int querymax(int rt,int l,int r,int x,int y){
if (r < x || l > y)
return -1e9;
if (l >= x && r <= y)
return tree[rt].maxn;
int mid = l + r >> 1;
return max(querymax(rt << 1,l,mid,x,y),querymax(rt << 1 | 1,mid+1,r,x,y));
}
int querysum(int rt,int l,int r,int x,int y){
if (r < x || l > y)
return 0;
if (l >= x && r <= y)
return tree[rt].sum;
int mid = l + r >> 1;
return querysum(rt << 1,l,mid,x,y) + querysum(rt << 1 | 1,mid + 1,r,x,y);
}
}Tree;
void dfs1(int u,int father){
dep[u] = dep[father] + 1;
fa[u] = father;
h[u] = -1,size[u] = 1;
for (int i=head[u];i;i=tree[i].next){
int v = tree[i].v;
if (v == father)
continue;
dfs1(v,u);
size[u] += size[v];
if (h[u] == -1 || size[v] > size[h[u]])
h[u] = v;
}
}
void dfs2(int u,int t){
top[u] = t;
dfn[u] = ++timer;rnk[timer] = u;
if (h[u] == -1)
return ;
dfs2(h[u],t);
for (int i=head[u];i;i=tree[i].next){
int v = tree[i].v;
if (v == fa[u] || v == h[u])
continue;
dfs2(v,v);
}
}
int querymax(int x,int y){
int fx = top[x],fy = top[y];
int res = -1e9;
while (fx != fy){
if (dep[fx] > dep[fy])
res = max(res,Tree.querymax(1,1,n,dfn[fx],x)),x = fa[fx];
else
res = max(res,Tree.querymax(1,1,n,dfn[fy],y)),y = fa[fy];
fx = top[x],fy = top[y];
}
if (dep[x] > dep[y])
res = max(res,Tree.querymax(1,1,n,dfn[y],dfn[x]));
else res = max(res,Tree.querymax(1,1,n,dfn[x],dfn[y]));
return res;
}
int querysum(int x,int y){
int fx = top[x],fy = top[y],res = 0;
while (fx != fy){
if (dep[fx] > dep[fy])
res += Tree.querysum(1,1,n,dfn[fx],dfn[x]),x = fa[fx];
else res += Tree.querysum(1,1,n,dfn[fy],dfn[y]),y = fa[fy];
fx = top[x],fy = top[y];
}
if (dep[x] > dep[y])
res += Tree.querysum(1,1,n,dfn[y],dfn[x]);
else res += Tree.querysum(1,1,n,dfn[x],dfn[y]);
return res;
}
signed main(){
n = read();
for (int i=1,u,v;i<n;i++){
u = read(); v = read();
add(u,v);
add(v,u);
}
for (int i=1;i<=n;i++)
val[i] = read();
m = read();
dfs1(1,0);
dfs2(1,1);
Tree.build(1,1,n);
for (int i=1,u,v;i<=m;i++){
cin >> s;
u = read();v = read();
if (s[0] == 'C'){
Tree.change(1,1,n,dfn[u],v);
} else if (s[0] == 'Q' && s[1] == 'M'){
printf("%lld\n",querymax(u,v));
} else printf("%lld\n",querysum(u,v));
}
return 0;
}//喵内~
/*
*/
回复
共 0 条回复,欢迎继续交流。
正在加载回复...