_Haoomff_ @ 2024-04-06 08:51:43
rt.
样例都不对。
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
typedef long long ll;
int head[N],nxt[N<<1],V[N<<1],edgenum,tim,size[N],son[N],dep[N],fa[N],top[N],in[N],n,m;
ll a[N],b[N];
struct node{
int l,r,len;
ll sum,lazy;
}tree[N<<2];
inline void push_up(int p){
tree[p].sum=tree[p<<1].sum+tree[p<<1|1].sum;
}
inline void build(int p,int l,int r){
tree[p].l=l;tree[p].r=r;tree[p].lazy=0;tree[p].len=r-l+1;
if(l==r){
tree[p].sum=b[l];
return;
}
int mid=l+(r-l>>1);
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
push_up(p);
}
inline void push_down(int p){
tree[p<<1].lazy+=tree[p].lazy;
tree[p<<1|1].lazy+=tree[p].lazy;
tree[p<<1].sum+=tree[p].lazy*tree[p<<1].len;
tree[p<<1|1].sum+=tree[p].lazy*tree[p<<1|1].len;
tree[p].lazy=0;
}
inline void update(int p,ll v,int l,int r){
if(tree[p].r<l||tree[p].l>r)return;
if(l<=tree[p].l&&tree[p].r<=r){
tree[p].sum+=v*tree[p].len;
if(tree[p].l<tree[p].r)tree[p].lazy+=v;
return;
}
push_down(p);
update(p<<1,v,l,r);
update(p<<1|1,v,l,r);
push_up(p);
}
inline ll query(int p,int l,int r){
if(tree[p].r<l||tree[p].l>r)return 0LL;
if(l<=tree[p].l&&tree[p].r<=r)return tree[p].sum;
push_down(p);
return query(p<<1,l,r)+query(p<<1|1,l,r);
}
inline void add(int u,int v){
V[++edgenum]=v;
nxt[edgenum]=head[u];
head[u]=edgenum;
}
inline void dfs(int u,int father){
dep[u]=dep[father]+1;
fa[u]=father;
size[u]=1;
for(int e=head[u];e;e=nxt[e])
if(V[e]!=father){
dfs(V[e],u);
size[u]+=size[V[e]];
if(size[V[e]]>size[son[u]])son[u]=V[e];
}
}
inline void dfs1(int u,int t){
in[u]=++tim;
b[tim]=a[u];
top[u]=t;
if(!son[u])return;
dfs1(son[u],t);
for(int e=head[u];e;e=nxt[e])
if(V[e]!=fa[u]&&V[e]!=son[u])
dfs1(V[e],V[e]);
}
inline ll query(int x,int y){
ll res=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res+=query(1,in[top[x]],in[x]);
x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
res+=query(1,in[y],in[x]);
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1,u,v;i<n;++i){
cin>>u>>v;
add(u,v);
add(v,u);
}
dfs(1,0);
dfs1(1,1);
build(1,1,n);
for(int u,v;m--;){
char op;
cin>>op>>u>>v;
if(op=='P')update(1,1,in[u],in[v]);
else cout<<query(u,v)<<"\n";
}
return 0;
}
by yiming_328 @ 2024-06-10 11:42:27
@Haoomff 是边权不是点权呢
by yiming_328 @ 2024-06-10 11:46:09
@Haoomff 因为边权下赋,所以一操作取lca,二操作直接用线段树取子结点点权