社区讨论

求调RE

P2542[AHOI2005] 航线规划参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@m69gblhb
此快照首次捕获于
2025/01/23 22:51
去年
此快照最后确认于
2025/11/04 10:47
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define ls (p<<1)
#define rs (ls|1)
#define pl pair<int,int>
using namespace std;

const int N=6e4+5,M=2e5+5;
int n,m,k,root,head[N],cnt;
int siz[N],son[N],dep[N],tot[N],id[N],idx,st[N];
struct nnd {
	int to,next;
}eg[M<<1];
inline void add(const int& from,const int& to){
	eg[cnt].to=to;
	eg[cnt].next=head[from];
	head[from]=cnt++;
}
inline void dfs1(const int& x,const int& fa){
	st[x]=fa;
	dep[x]=dep[fa]+1;
	for(int i=head[x];~i;i=eg[i].next){
		int to=eg[i].to;
		if(to==fa){
			continue;
		}
		dfs1(to,x);
		siz[x]+=siz[to];
		if(!son[x]||siz[to]>siz[son[x]]){
			son[x]=to;
		}
	}
}
inline void dfs2(const int& x,const int& totx){
	id[x]=++idx;
	tot[x]=totx;
	if(!son[x]){
		return;
	}
	dfs2(son[x],totx);
	for(int i=head[x];~i;i=eg[i].next){
		int to=eg[i].to;
		if(to!=st[x]&&to!=son[x]){
			dfs2(to,to);
		}
	}
}
struct node {
	int a,b;
	int sum,lazy;
}tree[N<<2];
inline void up_tree(const int& p){
	tree[p].sum=tree[ls].sum+tree[rs].sum;
}
inline void down_tree(const int& p){
	if(!tree[p].lazy||tree[p].a==tree[p].b){
		return;
	}
	tree[p].lazy=0;
	tree[ls].lazy=1;
	tree[ls].sum=0;
	tree[rs].lazy=1;
	tree[rs].sum=0;
}
inline void build_tree(const int& p,const int& x,const int& y){
	tree[p].a=x;
	tree[p].b=y;
	if(x==y){
		tree[p].sum=1;
		return;
	}
	int mid=x+y>>1;
	build_tree(ls,x,mid);
	build_tree(rs,mid+1,y);
	up_tree(p);
}
inline void change_tree(const int& p,const int& x,const int& y){
	down_tree(p);
	if(x<=tree[p].a&&tree[p].b<=y){
		tree[p].lazy=1;
		tree[p].sum=0;
		return;
	}
	if(x<=tree[ls].b){
		change_tree(ls,x,y);
	}
	if(tree[rs].a<=y){
		change_tree(rs,x,y);
	}
	up_tree(p);
}
inline int get_tree(const int& p,const int& x,const int& y){
	down_tree(p);
	if(x<=tree[p].a&&tree[p].b<=y){
		return tree[p].sum;
	}
	int ans=0;
	if(x<=tree[ls].b){
		ans+=get_tree(ls,x,y);
	}
	if(tree[rs].a<=y){
		ans+=get_tree(rs,x,y);
	}
	return ans;
}
inline void change_lca(int x,int y){
	if(x==y)return;
	while(tot[x]!=tot[y]){
		if(dep[tot[x]]<dep[tot[y]]){
			swap(x,y);
		}
		int totx=tot[x];
		change_tree(1,id[totx],id[x]);
		x=st[totx];
	}
	if(dep[x]<dep[y]){
		swap(x,y);
	}
	if(x!=y){
		change_tree(1,id[y]+1,id[x]);
	}
}
inline int get_lca(int x,int y){
	if(x==y)return 0;
	int ans=0;
	while(tot[x]!=tot[y]){
		if(dep[tot[x]]<dep[tot[y]]){
			swap(x,y);
		}
		int totx=tot[x];
		ans+=get_tree(1,id[totx],id[x]);
		x=st[totx];
	}
	if(dep[x]<dep[y]){
		swap(x,y);
	}
	if(x!=y){
		ans+=get_tree(1,id[y]+1,id[x]);
	}
	return ans;
}
map<pl,bool>mp;
struct mmb {
	int x,y,vis;
}A[M<<1],B[M<<1];
int fa[N];
void init(){
	for(int i=1;i<=n;i++){
		fa[i]=i;
		siz[i]=1;
		head[i]=-1;
	}
	cnt=idx=0;
}
inline int find(const int& x){
	if(fa[x]==x){
		return x;
	} else {
		return fa[x]=find(fa[x]);
	}
}
stack<int>ans;

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin>>n>>m;
	init();
	for(int i=1;i<=m;i++){
		cin>>A[i].x>>A[i].y;
	}
	while(1){
		int w,x,y;
		cin>>w;
		if(w==-1){
			break;
		}
		k++;
		cin>>B[k].x>>B[k].y;
		mp[pl(B[k].x,B[k].y)]=1;
		B[k].vis=w;
	}
	for(int i=1;i<=m;i++){
		if(mp[pl(A[i].x,A[i].y)]||mp[pl(A[i].y,A[i].x)]){
			A[i].vis=2;
			continue;
		}
		int x=find(A[i].x),y=find(A[i].y);
		if(x!=y) {
			fa[y]=x;
			add(A[i].x,A[i].y);
			add(A[i].y,A[i].x);
		} else {
			A[i].vis=1;
		}
	}
	dep[0]=-1;
	dfs1(1,0);
	dfs2(1,1);
	build_tree(1,1,n);
	for(int i=1;i<=m;i++){
		if(A[i].vis==1){
			change_lca(A[i].x,A[i].y);
		}
	}
	for(int i=k;i;i--){
		if(B[i].vis){
			ans.push(get_lca(B[i].x,B[i].y));
		} else {
			change_lca(B[i].x,B[i].y);
		}
	}
	while(ans.size()){
		cout<<ans.top()<<"\n";
		ans.pop();
	}
	
	return 0;
}	

回复

0 条回复,欢迎继续交流。

正在加载回复...