HNOI2016网络


加入删除都有

线段树分治?二进制分组?整体二分?

线段树分治时间轴建树,询问修改各(nlog)

但是咋处理询问!?是不经过的最大值

瞄了眼之前的代码 又作弊!

竟然是整体二分

把大于(mid)的加入,若经过的=总共加入的->([l,mid]),否则到右半段

树状数组即可

时间复杂度(O(nlog^2n))

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
const int N=1e5+4;
struct Ques{int u,v,w;}Q[N<<1];
struct ques{int u,v,w,t,id;}q[N<<1],q1[N<<1],q2[N<<1];
int dep[N],siz[N],fa[N],son[N],st[N],ed[N],top[N],tim=0;
vector<int>e[N];
int n,m,t[N],ans[N<<1],cnt=0,num=0;
void dfs_1(int x){
	dep[x]=dep[fa[x]]+1;
	siz[x]=1;
	for(auto v:e[x]){
		if(v==fa[x])continue;
		fa[v]=x;
		dfs_1(v);
		siz[x]+=siz[v];
		if(siz[v]>siz[son[x]])son[x]=v;
	}
} 
void dfs_2(int x,int tp){
	top[x]=tp;
	st[x]=++tim;
	if(son[x])dfs_2(son[x],tp);
	for(auto v:e[x]){
		if(v==fa[x]||v==son[x])continue;
		dfs_2(v,v);
	}
	ed[x]=tim;
}
inline int getlca(int u,int v){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])u^=v^=u^=v;
		u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}
inline void add(int x,int v){
	if(!x)return;
	for(;x<=n;x+=x&-x)t[x]+=v;
}
inline int ask(int x){
	int ret=0;
	for(;x;x-=x&-x)ret+=t[x];
	return ret;
}
void solve(int al,int ar,int ql,int qr){
	if(ql>qr)return;
	if(al==ar){
		if(!ar)ar=-1;
		for(int i=ql;i<=qr;i++)
			if(!q[i].id)ans[q[i].w]=ar;
		return;
	}
	int mid=al+ar>>1,cn1=0,cn2=0;
	for(int i=ql,lca,lei=0,c;i<=qr;i++){
		if(!q[i].id){
			if(ask(ed[q[i].u])-ask(st[q[i].u]-1)==lei)q1[++cn1]=q[i];
			else q2[++cn2]=q[i];
		}
		else if(q[i].w>mid){
			lca=getlca(q[i].u,q[i].v);
			c=q[i].id;
			lei+=c;
			add(st[q[i].u],c);add(st[q[i].v],c);
			add(st[lca],-c);add(st[fa[lca]],-c);
			q2[++cn2]=q[i];
		}
		else q1[++cn1]=q[i];
	}
	for(int i=ql,lca,c;i<=qr;i++)
		if(q[i].id&&q[i].w>mid){
			lca=getlca(q[i].u,q[i].v);
			c=q[i].id;
			add(st[q[i].u],-c);add(st[q[i].v],-c);
			add(st[lca],c);add(st[fa[lca]],c);
		}
	for(int i=1;i<=cn1;i++)q[ql+i-1]=q1[i];
	for(int i=1;i<=cn2;i++)q[ql+cn1+i-1]=q2[i];
	solve(al,mid,ql,ql+cn1-1);solve(mid+1,ar,ql+cn1,qr); 
}
int main(){
	n=read();m=read();
	for(int i=1,u,v;i<n;i++){
		u=read();v=read();
		e[u].push_back(v);e[v].push_back(u);
	} 
	dfs_1(1);
	dfs_2(1,1);
	for(int i=1,op,u,v,w;i<=m;i++){
		op=read();u=read();
		if(op==1)q[++cnt]=(ques){Q[u].u,Q[u].v,Q[u].w,i,-1};
		else if(op==2)q[++cnt]=(ques){u,0,++num,i,0};
		else{
			v=read();w=read();
			q[++cnt]=(ques){u,v,w,i,1};
			Q[i]=(Ques){u,v,w}; 
		}
	}
	solve(0,1e9,1,cnt);
	for(int i=1;i<=num;i++)cout<<ans[i]<<"
";
	return (0-0);
}
原文地址:https://www.cnblogs.com/aurora2004/p/12628804.html