树链剖分求调,悬关
查看原帖
树链剖分求调,悬关
368111
_Haoomff_楼主2024/3/31 09:23

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=a[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_point(int p,ll v,int x){
	if(tree[p].r<x||tree[p].l>x)return;
	if(tree[p].l==tree[p].r){
		tree[p].sum+=v;
		return;
	}
	update_point(p<<1,v,x);
	update_point(p<<1|1,v,x);
	push_up(p);
}
inline void update_tree(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_tree(p<<1,v,l,r);
	update_tree(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;i<=n;++i)cin>>a[i];
	for(int i=1,fr,to;i<n;++i){
		cin>>fr>>to;
		add(fr,to);
		add(to,fr);
	} 
	dfs(1,0);
	dfs1(1,1);
	build(1,1,n);
	for(int op,x;m--;){
		ll a;
		cin>>op>>x;
		if(op==1){
			cin>>a;
			update_point(1,a,in[x]);
		}
		else if(op==2){
			cin>>a;
			update_tree(1,a,in[x],in[x]+size[x]-1);
		}
		else cout<<query(1,x)<<"\n";
	}
	return 0;
}
2024/3/31 09:23
加载中...