树剖WA70pts求助
查看原帖
树剖WA70pts求助
685536
david0911楼主2024/7/22 17:51

rt,悬关。

离线做法,代码如下

#include<bits/stdc++.h>

using namespace std;

const int maxn=3e4+10,maxm=1e5+10,maxq=4e4+10;
int n,m,cnt=0,tt,dfn,anstot,f[maxn],ans[maxq],head[maxn],son[maxn],siz[maxn],val[maxn],wv[maxn],id[maxn],dep[maxn],fa[maxn],tp[maxn];
bool vis[maxm];
map< pair<int,int>,bool > ava;
pair<int,int> e1[maxm];
struct edge{
	int u,v,w,nxt;
}e[maxm];
struct data{
	int typ,u,v;
}q[maxq];
struct TREE{
	int sum,tag;
}t[maxn<<2];

int find(int u){
	if(u==f[u]) return u;
	return f[u]=find(f[u]);
}

#define ls(k) k<<1
#define rs(k) k<<1|1

void pushup(int k){
	t[k].sum=t[ls(k)].sum+t[rs(k)].sum;
}

void pushdown(int k){
	if(t[k].tag!=-1){
		t[ls(k)].sum=t[rs(k)].sum=t[ls(k)].tag=t[rs(k)].tag=0;
		t[k].tag=-1;
	}
}

void build(int k,int l,int r){
	t[k].tag=-1;
	if(l==r){
		t[k].sum=wv[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls(k),l,mid);
	build(rs(k),mid+1,r);
	pushup(k);
}

void upd(int k,int l,int r,int ql,int qr){
	if(ql>qr) return;
	pushdown(k);
	if(ql<=l&&r<=qr){
		t[k].sum=t[k].tag=0;
		return;
	}
	int mid=(l+r)>>1;
	if(ql<=mid) upd(ls(k),l,mid,ql,qr);
	if(mid<qr) upd(rs(k),mid+1,r,ql,qr);
	pushup(k);
}

int query(int k,int l,int r,int ql,int qr){
	if(ql>qr) return 0;
	pushdown(k);
	if(ql<=l&&r<=qr) return t[k].sum;
	int mid=(l+r)>>1,res=0;
	if(ql<=mid) res+=query(ls(k),l,mid,ql,qr);
	if(mid<qr) res+=query(rs(k),mid+1,r,ql,qr);
	return res;
}

inline void add(int u,int v){
	e[++tt].u=u;
	e[tt].v=v;
	e[tt].w=1;
	e[tt].nxt=head[u];
	head[u]=tt;
}

void dfs1(int u,int ff,int w){
	fa[u]=ff;
	dep[u]=dep[ff]+1;
	son[u]=-1;
	siz[u]=1;
	val[u]=w;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==ff) continue;
		dfs1(v,u,e[i].w);
		siz[u]+=siz[v];
		if(son[u]==-1||siz[son[u]]<siz[v]) son[u]=v;
	}
}

void dfs2(int u,int p){
	tp[u]=p;
	id[u]=++dfn;
	wv[dfn]=val[u];
	if(son[u]==-1) return;
	dfs2(son[u],p);
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}

void updline(int u,int v){
	while(tp[u]!=tp[v]){
		if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
		upd(1,1,dfn,id[tp[u]],id[u]);
		u=fa[tp[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	upd(1,1,dfn,id[u]+1,id[v]);
}

int qline(int u,int v){
	int res=0;
	while(tp[u]!=tp[v]){
		if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
		res+=query(1,1,dfn,id[tp[u]],id[u]);
		u=fa[tp[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	res+=query(1,1,dfn,id[u]+1,id[v]);	
	return res;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i){
		int u,v;
		scanf("%d%d",&u,&v);
		e1[i]=make_pair(u,v);
	}
	for(int i=1;i<=n;++i) f[i]=i;
	while(true){
		int op,u,v;
		scanf("%d",&op);
		if(op==-1) break;
		scanf("%d%d",&u,&v);
		q[++cnt]=(data){op,u,v};
		if(!op) ava[make_pair(u,v)]=ava[make_pair(v,u)]=1;
	}
	for(int i=1;i<=m;++i){
		int u=e1[i].first,v=e1[i].second;
		int fu=find(u),fv=find(v);
		if(!ava[make_pair(u,v)]&&fu!=fv){
			add(u,v),add(v,u);
			f[fu]=fv;
			vis[i]=true;
		}
	}
	dfs1(1,0,0);
	dfs2(1,1);
	build(1,1,n);
	for(int i=1;i<=m;++i){
		int u=e1[i].first,v=e1[i].second;
		if(!vis[i]&&!ava[make_pair(u,v)]) updline(u,v);
	}
	for(int i=cnt;i>=1;--i){
		if(q[i].typ) ans[++anstot]=qline(q[i].u,q[i].v);
		else updline(q[i].u,q[i].v);
	}
	for(int i=anstot;i>=1;--i) printf("%d\n",ans[i]);
	return 0;
}
2024/7/22 17:51
加载中...