MnZn求助,WA on 6 90分
查看原帖
MnZn求助,WA on 6 90分
1024338
Le0Chan楼主2023/11/1 10:33

做法:边双缩点+树剖

#include <bits/stdc++.h>
using namespace std;

#define pii pair<int,int>
#define fi first
#define se second

const int M=1e5+5;
const int N=3e4+5;

int n,m,cnt=1,df,bcc,tot;
int head[N],dep[N],dfn[N],low[N],ct[M<<1],vis[N],bel[N],siz[N],son[N],f[N],top[N],ans[N];

struct edge{
	int x,y,op;
}b[M];

struct node{
	int to,ne;
}e[M];

void add(int x,int y){
	e[++cnt]=(node){y,head[x]};
	head[x]=cnt;
}

void tarjan(int x,int ed){
	dfn[x]=low[x]=++df;
	ed^=1;
	for(int i=head[x];i;i=e[i].ne){
		int y=e[i].to;
		if(!dfn[y]){
			tarjan(y,i);
			low[x]=min(low[x],low[y]);
			if(low[y]>dfn[x]){
				ct[i]=ct[i^1]=1;
			}
		}else if(i!=ed) low[x]=min(low[x],dfn[y]);
	}
}

void dfs(int x){
	vis[x]=1;
	bel[x]=bcc;
	for(int i=head[x];i;i=e[i].ne){
		if(!ct[i]){
			int y=e[i].to;
			if(!vis[y]){
				dfs(y);
			}
		}
	}
}

struct mm{
	int x,y;
}c[M];

map<pii,int> mp;

vector<int> g[N];

void add2(int x,int y){
	g[x].push_back(y);
}

void dfs2(int x,int fa){
	siz[x]=1;
	dep[x]=dep[fa]+1;
	f[x]=fa;
	for(int y:g[x]){
		if(y!=fa){
			dfs2(y,x);
			siz[x]+=siz[y];
			if(siz[y]>siz[son[x]]){
				son[x]=y;
			}
		}
	}
}

void dfs3(int x,int tp){
	top[x]=tp;
	dfn[x]=++df;
	if(son[x]) dfs3(son[x],tp);
	for(int y:g[x]){
		if(y!=f[x]&&y!=son[x]){
//			cout<<x<<" "<<y<<"\n";
			dfs3(y,y);
		}
	}
}

struct tr{
	int t[N<<2],tg[N<<2];
	tr(){memset(tg,-1,sizeof(tg));}
	void pp(int p){
		t[p]=t[p<<1]+t[p<<1|1];
	}
	void build(int p,int l,int r){
		if(l==r){
			t[p]=1;
			return ;
		}
		int mid=l+r>>1;
		build(p<<1,l,mid);
		build(p<<1|1,mid+1,r);
		pp(p);
	}
	void add(int p,int l,int r){
		t[p]=0;
		tg[p]=0;
	}
	void pd(int p,int l,int r){
		if(tg[p]!=-1){
			int mid=l+r>>1;
			add(p<<1,l,mid);
			add(p<<1|1,mid+1,r);
			tg[p]=-1;
		}
	}
	void modify(int p,int l,int r,int ql,int qr){
		if(l>=ql&&r<=qr){
			add(p,l,r);
			return ;
		}
		int mid=l+r>>1;
		pd(p,l,r);
		if(ql<=mid) modify(p<<1,l,mid,ql,qr);
		if(qr>mid) modify(p<<1|1,mid+1,r,ql,qr);
		pp(p);
	}
	int query(int p,int l,int r,int ql,int qr){
		if(l>=ql&&r<=qr){
			return t[p];
		}
		int mid=l+r>>1;
		int sm=0;
		pd(p,l,r);
		if(ql<=mid) sm+=query(p<<1,l,mid,ql,qr);
		if(qr>mid) sm+=query(p<<1|1,mid+1,r,ql,qr);
		return sm;
	}
}sg;

void mroad(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		sg.modify(1,1,bcc,dfn[top[x]],dfn[x]);
		x=f[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	if(x==y){
		return ;
	}
	sg.modify(1,1,bcc,dfn[x]+1,dfn[y]);
}

void qroad(int x,int y,int id){
	int sm=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		sm+=sg.query(1,1,bcc,dfn[top[x]],dfn[x]);
		x=f[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	if(x==y){
		ans[id]=sm;
		return ;
	}
	sm+=sg.query(1,1,bcc,dfn[x]+1,dfn[y]);
	ans[id]=sm;
}

int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m;
	for(int i=1,x,y;i<=m;i++){
		cin>>x>>y;
		c[i]=(mm){x,y};
	}
	while(1){
		int op,x,y;
		cin>>op;
		if(op==-1) break;
		cin>>x>>y;
		b[++tot]=(edge){x,y,op};
		if(op==0){
			mp[{x,y}]=mp[{y,x}]=1;
		}
	}
	for(int i=1;i<=m;i++){
		int x=c[i].x,y=c[i].y;
		if(!mp[{x,y}]){
			add(x,y);
			add(y,x);
		}
	}
	tarjan(1,0);
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			bcc++;
			dfs(i);
		}
	}
	for(int x=1;x<=n;x++){
		for(int i=head[x];i;i=e[i].ne){
			int y=e[i].to;
			if(bel[x]!=bel[y]){
				add2(bel[x],bel[y]);
			}
		}
	}
	df=0;
	dfs2(bel[1],0);
	dfs3(bel[1],bel[1]);
	sg.build(1,1,bcc);
	for(int i=tot;i>=1;i--){
		int x=b[i].x,y=b[i].y,op=b[i].op;
		if(op==1){
			qroad(bel[x],bel[y],i);
		}
		else{
			mroad(bel[x],bel[y]);
		}
	}
	for(int i=1;i<=tot;i++){
		if(b[i].op==1)
		cout<<ans[i]<<"\n";
	}
	return 0;
}

2023/11/1 10:33
加载中...