线段树合并求救(WA95

蒟蒻第一次写就写挂了,LCA没问题
( P4556 [Vani有约会] 雨天的尾巴 /【模板】线段树合并 - 洛谷 | 计算机科学教育新生态)

#include<bits/stdc++.h>
#define ls sgm[sgm[rt].l]
#define rs sgm[sgm[rt].r]
#define lp sgm[rt].l
#define rp sgm[rt].r
const int N=1e5+5;
using namespace std;
int head[N],cnt;
int dfn;
int n,q,root[N],cnt_sgm;
//不会倍增LCA所以简简单单写个树剖求LCA吧 
struct node{int size,top,son,dep,fa,id;}p[N];
struct edge{int next,to;}e[N<<2];
struct tree{int l,r,ans,mx;}sgm[N<<7]; 
void add_edge(int u,int v){e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
void dfs(int u,int fa){
    p[u].fa=fa;p[u].size=1;p[u].dep=p[fa].dep+1;
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==fa) continue;
        dfs(v,u);p[u].size+=p[v].size;
        if(p[u].son==0|p[v].size>p[p[u].son].size) p[u].son=v;//重儿子
    }
}
void dfs2(int u,int t){
    p[u].id=++dfn;p[u].top=t;
    if(!p[u].son) return;
    dfs2(p[u].son,t);//先遍历重儿子
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to; 
        if(v==p[u].fa||v==p[u].son) continue;
        dfs2(v,v);
    }   
}
int lca(int x,int y){
    while(p[x].top!=p[y].top){
        if(p[p[x].top].dep<p[p[y].top].dep){swap(x,y);}
        x=p[p[x].top].fa;
    }
    if(p[x].dep<p[y].dep){swap(x,y);}
    return y;
}
void update(int rt){
	if(ls.mx>=rs.mx){
		sgm[rt].mx=ls.mx,sgm[rt].ans=ls.ans;
	}
	else{
		sgm[rt].mx=rs.mx,sgm[rt].ans=rs.ans;
	}
}
void insert(int &rt,int l,int r,int x,int k){ 
	if(!rt) {rt=++cnt_sgm;}
	if(l==r&&l==x){sgm[rt].mx+=k;sgm[rt].ans=x;return;}
	int mid=(l+r)>>1;
	if(x<=mid) insert(lp,l,mid,x,k);
	else insert(rp,mid+1,r,x,k);
	update(rt); 
}
int merge(int p1,int p2,int l,int r){//线段树合并 
	//cerr<<l<<" "<<r<<endl; 
	if(!p1||!p2) return p1+p2;
	int rt=++cnt_sgm,mid=(l+r)>>1;
	if(l==r){sgm[rt].mx=sgm[p1].mx+sgm[p2].mx;sgm[rt].ans=l;return rt;}
	lp=merge(sgm[p1].l,sgm[p2].l,l,mid);
	rp=merge(sgm[p1].r,sgm[p2].r,mid+1,r);
	update(rt);return rt;
}
void up(int u,int fa){
	for(int i=head[u];i;i=e[i].next){
		int v=e[i].to;
		if(v==fa) continue;
		//cout<<"edge:"<<u<<v<<endl;
		up(v,u);
		root[u]=merge(root[u],root[v],1,N-5);
	}
}
int main(){
    cin>>n>>q;
    for(int i=1;i<=n-1;i++){
        int x,y;
        cin>>x>>y;
        add_edge(x,y);
        add_edge(y,x);
    }
    add_edge(0,1);add_edge(1,0);
    dfs(1,0);
    dfs2(1,0);
    for(int i=1;i<=q;i++){
    	int x,y,z,l;
    	cin>>x>>y>>z;
    	l=lca(x,y);
    //	cout<<"LCA:"<<l<<endl;
		insert(root[p[l].fa],1,N-5,z,-1);
		//cerr<<"#"<<endl; 
    	insert(root[l],1,N-5,z,-1);
    	//cerr<<"#"<<endl; 
    	insert(root[x],1,N-5,z,1);
    	//cerr<<"#"<<endl; 
    	insert(root[y],1,N-5,z,1);
    	//cerr<<"#"<<endl; 
	}
	up(1,0);
	for(int i=1;i<=n;i++){
		cout<<sgm[root[i]].ans<<endl;
	} 
    return 0;
}
1 个赞

额合并有个地方写错了,现在wa95

1 个赞

额这个输出时候要特判一下不能单纯输出ans,因为mx可能=0

1 个赞