树剖求助
查看原帖
树剖求助
305854
Drind楼主2023/9/18 22:40

RT,把样例下下来发现有的地方答案更大,或者答案不为 -1 却输出 -1 的情况,盲猜是链操作写炸了或者线段树炸了,没调出来

6pts

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+10;

struct segtree{
	int l,r,w,lazy;
}tree[N*4];

struct node{
	int to,nxt;
}edge[N]; int head[N],cnt;
void add(int u,int v){
	edge[++cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}
void adde(int u,int v){
	add(u,v); add(v,u);
}

struct node2{
	int u,v;
}E[N]; int cnt2;

int fa[N],son[N],siz[N],dep[N];
int top[N],id[N],rev[N],res;

void dfs1(int u,int f){
	siz[u]=1;
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to; if(v==f) continue;
	//	cout<<u<<" "<<v<<endl;
		fa[v]=u; dep[v]=dep[u]+1; 
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[son[u]]<siz[v]) son[u]=v;
	}
} 

void dfs2(int u,int tp){
	id[u]=++res; rev[res]=u;
	top[u]=tp; if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i=head[u];i;i=edge[i].nxt){
		int v=edge[i].to; if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}

void pushup(int x){
	tree[x].w=min(tree[x*2].w,tree[x*2+1].w); 
} 

void pushdown(int x){
	int tag=tree[x].lazy;
	if(tag==-1) return;
	tree[x].lazy=-1;
	tree[x*2].w=min(tree[x*2].w,tag);
	tree[x*2+1].w=min(tree[x*2+1].w,tag);
	tree[x*2].lazy=min(tree[x*2].lazy,tag);
	tree[x*2+1].lazy=min(tree[x*2+1].lazy,tag);
}

void build(int x,int l,int r){
	tree[x].l=l; tree[x].r=r;
	tree[x].lazy=-1;
	if(l==r){
		tree[x].w=1e15;
		return;
	}
	int mid=(l+r)/2;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
	pushup(x);
}

int query(int x,int l,int r){
	if(tree[x].l>=l&&tree[x].r<=r)
		return tree[x].w; 
	int mid=(tree[x].l+tree[x].r)/2;
	int ans=1e15;
	pushdown(x);
	if(l<=mid) ans=min(ans,query(x*2,l,r));
	if(r>mid) ans=min(ans,query(x*2+1,l,r));
	return ans;
}

int linkquery(int u,int v){
	int ans=1e15;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		ans=min(ans,query(1,id[top[u]],id[u]));
		u=fa[top[u]];
	}
	if(dep[v]<dep[u]) swap(u,v);
	ans=min(ans,query(1,id[u]+1,id[v]));
	return ans;
}

void modify(int x,int l,int r,int val){
	if(tree[x].l>=l&&tree[x].r<=r){
		tree[x].w=min(val,tree[x].w);
		tree[x].lazy=min(val,tree[x].lazy); return;
	}
	pushdown(x);
	int mid=(tree[x].l+tree[x].r)/2;
	if(l<=mid) modify(x*2,l,r,val);
	if(r>mid) modify(x*2+1,l,r,val);
	pushup(x);
}

void linkmodify(int u,int v,int val){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		modify(1,id[top[u]],id[u],val);
		u=fa[top[u]];
	}
	if(dep[v]<dep[u]) swap(u,v);
	modify(1,id[u]+1,id[v],val);
}

inline void fake_main(){
	int n,m; cin>>n>>m;
	for(int i=1;i<n;i++){
		int u,v; cin>>u>>v; adde(u,v);
		E[++cnt2].u=u; E[cnt2].v=v;
	}
	
	dfs1(1,0); dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int u,v,w; cin>>u>>v>>w;
		linkmodify(u,v,w);
	}
	for(int i=1;i<=cnt2;i++){
		int t=linkquery(E[i].u,E[i].v);
		//int u=E[i].u,v=E[i].v;
		//int tmp=dep[u]>dep[v]?id[u]:id[v];
		//int t=query(1,tmp,tmp);
		if(t!=1e15) cout<<t<<"\n";
		else cout<<"-1\n";
	}
}

signed main(){
	ios::sync_with_stdio(false);
	int t; t=1;
	while(t--) fake_main();
}

2023/9/18 22:40
加载中...