树剖求助,全WA,悬赏3个关注
查看原帖
树剖求助,全WA,悬赏3个关注
241817
Chancylaser楼主2023/6/28 23:30

具体思路就是把 ii 的父亲到 ii 的边 看做 ii 的点权,查询max时不查询根节点的max(因为根节点上面没有父亲.)


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+5, INF=1e9;

int fst[N<<1],nxt[N<<1],T[N<<1],W[N<<1],tot,wh[N];
void add_edge(int a,int b,int c,int i){
	nxt[++tot]=fst[a];
	fst[a]=tot;
	T[tot]=b;
	W[tot]=c;
	wh[tot]=i;
}

int dep[N],f[N],siz[N],son[N], pos[N], beg[N];
void dfs(int p,int fp){
	dep[p]=dep[fp]+1;
	f[p]=fp;
	siz[p]=1;
	for(int i=fst[p];i;i=nxt[i]){
		int j=T[i];
		if(j==fp) continue;
		dfs(j,p);
		
		siz[p]+=siz[j];
		if(siz[j]>siz[son[p]]) son[p]=j;
		pos[wh[i]]=j;
		beg[j]=W[i];
	} 
}
int rk[N],id[N],top[N],cnt;
void dfs2(int p,int fp){
	top[p]=fp;
	rk[++cnt]=p;
	id[p]=cnt;
	if(!son[p]) return;
	dfs2(son[p],fp);
	for(int i=fst[p];i;i=nxt[i]){
		int j=T[i];
		if(j!=f[p] && j!=son[p])
			dfs2(j,j);
	}
}

int n;

struct qwq{
	int l,r;
	int max;
	int laz,fg;
	qwq(){
		l=r=0;
		max=laz=0;
		fg=-1;
	}
	
	void color1(int k){ //区间覆盖 
		max=k;
		laz=0; fg=k;
	}
	void color2(int k){ //区间加 
		max+=k;
		laz+=k;
	}
}t[N<<2];

qwq operator+(const qwq &a,const qwq &b){
	qwq c;
	c.l=a.l; c.r=b.r;
	c.max=max(a.max,b.max);
	return c;
}

void build(int p,int l,int r){
	if(l==r){
		t[p].l=l; t[p].r=r;
		t[p].max=beg[rk[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p]=t[p<<1]+t[p<<1|1];
}

void pushdown(int p){
	if(t[p].fg!=-1){
		t[p<<1].color1(t[p].fg);
		t[p<<1|1].color1(t[p].fg);
		t[p].fg=-1;
	}
	if(t[p].laz){
		t[p<<1].color2(t[p].laz);
		t[p<<1|1].color2(t[p].laz);
		t[p].laz=0;
	}
}

void fugai(int p,int l,int r,int k){
	if(t[p].l>r || t[p].r<l) return;
	if(t[p].l>=l && t[p].r<=r){
		t[p].color1(k);
		return;
	}
	pushdown(p);
	
	fugai(p<<1,l,r,k);
	fugai(p<<1|1,l,r,k);
	t[p]=t[p<<1]+t[p<<1|1];
}

void add(int p,int l,int r,int k){
	if(t[p].l>r || t[p].r<l) return;
	if(t[p].l>=l && t[p].r<=r){
		t[p].color2(k);
		return;
	}
	pushdown(p);
	
	add(p<<1,l,r,k);
	add(p<<1|1,l,r,k);
	t[p]=t[p<<1]+t[p<<1|1];
}

int getmax(int p,int l,int r){
	if(t[p].l>r || t[p].r<l) return 0;
	if(t[p].l>=l && t[p].r<=r) return t[p].max;
	
	pushdown(p);
	int ans=max(getmax(p<<1,l,r),getmax(p<<1|1,l,r));
	return ans;
}


void cz1(int k,int w){
	fugai(1,id[pos[k]],id[pos[k]],w);
}
void cz2(int u,int v,int w){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		fugai(1,id[top[u]],id[u],w);
		u=f[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	fugai(1,id[u],id[v],w);	
}
void cz3(int u,int v,int w){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		add(1,id[top[u]],id[u],w);
		u=f[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	add(1,id[u],id[v],w);	
}
int cz4(int u,int v){
	int ans=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ans=max(ans,getmax(1,id[top[u]],id[u]));
		u=f[top[u]];
	}
	if(id[u]>id[v]) swap(u,v);
	if(id[u]!=1) ans=max(ans,getmax(1,id[u],id[v]));
	else if(id[u]+1<=id[v])
		ans=max(ans,getmax(1,id[u]+1,id[v]));
	return ans;
}

int main(){
//	freopen("1.in","r",stdin);
//	freopen("qwq.out","w",stdout);
	
	cin>>n;
	int u,v,w;
	for(int i=1;i<n;i++){
		cin>>u>>v>>w;
		add_edge(u,v,w,i);
		add_edge(v,u,w,i);
	}
	
	dfs(1,0);
	dfs2(1,1);
	build(1,1,n);
	
	char opt[15]; 
	int k;
	while(1){
		cin>>opt;
		if(opt[0]=='S') break;
		else if(opt[0]=='C' && opt[1]=='h'){
			cin>>k>>w;
			cz1(k,w);
		}
		else if(opt[0]=='C' && opt[1]=='o'){
			cin>>u>>v>>w;
			cz2(u,v,w);
		}
		else if(opt[0]=='A'){
			cin>>u>>v>>w;
			cz3(u,v,w);
		}
		else{
			cin>>u>>v;
			cout<<cz4(u,v)<<"\n";
		}
	}
	return 0;
}
2023/6/28 23:30
加载中...