代码理论上没有问题,求调
查看原帖
代码理论上没有问题,求调
741676
Usstzqqch_Iroha楼主2025/7/25 17:26
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 100005;
int d[4*maxn];
int a[maxn];
int lazy_tag[4*maxn];
vector<int> G[maxn];
int n,q;                                                                    
void build(int s,int t,int p){
	if(s==t){
		d[p]=a[s];
		return ;
	}
	int m = s+((t-s)>>1);
	build(s,m,p<<1);
	build(m+1,t,(p<<1)|1);
	d[p]=d[p<<1]+d[(p<<1)|1];
}
int getsum(int l,int r,int s,int t,int p){
	if(s>=l&&t<=r) return d[p];
	int m = s+((t-s)>>1),sum=0;
	if(lazy_tag[p]){
		d[p*2]+=lazy_tag[p]*(m-s+1);
		d[p*2+1]+=lazy_tag[p]*(t-m);
		lazy_tag[p*2]+=lazy_tag[p];
		lazy_tag[p*2+1]+=lazy_tag[p];
		lazy_tag[p]=0;
	}
	if(l<=m) sum=getsum(l,r,s,m,p*2);
	if(r>m) sum+=getsum(l,r,m+1,t,p*2+1);
	return sum;
}
void update(int l,int r,int c,int s,int t,int p){
	if(l<=s&&r>=t){
		d[p]+=(t-s+1)*c,lazy_tag[p]+=c;
		return ;
	}
	int m=s+((t-s)>>1);
	if(lazy_tag[p]&&s!=t){
		d[p*2]+=lazy_tag[p]*(m-s+1);
		d[p*2+1]+=lazy_tag[p]*(t-m);
		lazy_tag[p*2]+=lazy_tag[p];
		lazy_tag[p*2+1]+=lazy_tag[p];
		lazy_tag[p]=0;
	}
	if(l<=m) update(l,r,c,s,m,p*2);
	if(r>m) update(l,r,c,m+1,t,p*2+1);
	d[p]=d[p*2]+d[p*2+1];
}
map<signed,signed> remarkset1;//实际编号转理想编号 
signed fa[maxn];
void dfs_remark(int x,int Fa,int num){
	remarkset1[0]=0;
	remarkset1[x]=num;
	//remarkset2[num]=x;
	fa[x]=Fa;
	if(G[x].size()==1&&Fa!=0){
		return ;
	}
	for(int i=0;i<G[x].size();i++){
		if(G[x][i]==Fa) continue;
		dfs_remark(G[x][i],x,++num);
	}
}
int mxsub[maxn];
void checkmx(int k,int Fa){
	/*if(k==1){
		mxsub[k]=n;
		return ;
	}*/
	int ideal = remarkset1[k];
	if(G[k].size()==1&&Fa!=0){
		mxsub[k] = ideal;
		return ;
	}
	else{
		for(int i=0;i<G[k].size();i++){
			if(G[k][i]!=Fa) checkmx(G[k][i],k);
		}
		for(int i=0;i<G[k].size();i++){
			if(mxsub[k]<mxsub[G[k][i]]) mxsub[k] = mxsub[G[k][i]];
		}
		return ;
	}
}
signed main(){
	//freopen("snow.in","r",stdin);
	//freopen("snow.out","w",stdout);
	memset(a,0,sizeof(a));
	cin>>n>>q;
	int u,v;
	for(int i=1;i<=n-1;i++){
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs_remark(1,0,1); 
	checkmx(1,0);
	for(int i=1;i<=n;i++) cout<<fa[i]<<' ';
	build(1,n,1);
	for(int i=1;i<=q;i++){
	int opt,x,y,z;
	cin>>opt;
	if(opt==1){
		cin>>x>>z;
		y = mxsub[x];
		x = remarkset1[x];
		update(x,y,z,1,n,1);
	}
	else{
		cin>>x;
		y = mxsub[x];
		x = remarkset1[x];
		cout<<getsum(x,y,1,n,1)<<'\n';
		}
	}
}

思路大概是利用dfs序重新编号使每一颗子树内部节点的编号是连续的区间且根节点是区间的左闭端点,然后利用线段树进行查询,但是没有找到错的地方

2025/7/25 17:26
加载中...