15 pts 求调
查看原帖
15 pts 求调
928972
ny_Dacong楼主2025/1/23 09:07

rt,缩点之后跑树剖,标记每条边的方向(往树根走还是往叶子走)。然后递归求答案。

WA 15 pts。

原图是链式前向星,新图是邻接矩阵 utd

#include<bits/stdc++.h>
using namespace std;
int n,m,q;
int etot = 0,Last[200050],Next[400050],Start[400050],End[400050],id[400050];
void addedge(int u,int v,int i){
	etot++;
	Next[etot] = Last[u];
	Last[u] = etot;
	Start[etot] = u;
	End[etot] = v;
	id[etot] = i;
	return;
}
stack<int> que;
bitset<200050> inque;
int dtot = 0,stot = 0,dfn[200050],low[200050],belong[200050];
void tarjan(int now,int Head){
	dfn[now] = low[now] = ++dtot;
	que.push(now),inque[now] = 1;
	for(int i = Last[now]; i; i = Next[i]){
		if(abs(id[i]) == Head){
			continue;
		}
		if(!dfn[End[i]]){
			tarjan(End[i],abs(id[i]));
			low[now] = min(low[now],low[End[i]]);
		}else if(inque[End[i]]){
			low[now] = min(low[now],dfn[End[i]]);
		}
	}
	if(dfn[now] == low[now]){
		int y;
		stot++;
		do{
			y = que.top();
			que.pop();
			inque[y] = 0;
			belong[y] = stot;
		}while(y != now);
	}
	return;
}
vector<pair<int,int>> utd[200050];
int ntot = 0,Size[200050],fat[200050],dep[200050],Head[200050];
int top[200050],val[200050];
void dfs1(int now,int fa){
	Size[now] = 1,fat[now] = 0,dep[now] = dep[fa]+1,Head[now] = fa;
	for(auto i:utd[now]){
		if(i.first == fa){
			continue;
		}
		dfs1(i.first,now);
		Size[now] += Size[i.first];
		if(fat[now] == 0 || Size[fat[now]] < Size[i.first]){
			fat[now] = i.first;
		}
	}
	return;
}
void dfs2(int now,int fa){
	val[now] = ++ntot,top[now] = fa;
	if(fat[now]){
		dfs2(fat[now],fa);
	}
	for(auto i:utd[now]){
		if(val[i.first]){
			continue;
		}
		dfs2(i.first,i.first);
	}
	return;
}
int tree[200050<<2],tag[200050<<2];
int ls(int x){
	return x<<1;
}
int rs(int x){
	return x<<1|1;
}
void push_up(int p){
	tree[p] = tree[ls(p)]+tree[rs(p)];
	return;
}
void addtag(int p,int pl,int pr,int opt){
	tag[p] += opt;
	tree[p] += opt*(pr-pl+1);
	return;
}
void push_down(int p,int pl,int pr){
	if(tag[p] != 0){
		int mid = pl+((pr-pl)>>1);
		addtag(ls(p),pl,mid,tag[p]);
		addtag(rs(p),mid+1,pr,tag[p]);
		tag[p] = 0;
	}
	return;
}
void modify(int p,int pl,int pr,int l,int r,int opt){
	if(l <= pl && pr <= r){
		addtag(p,pl,pr,opt);
		return;
	}
	int mid = pl+((pr-pl)>>1);
	push_down(p,pl,pr);
	if(l <= mid){
		modify(ls(p),pl,mid,l,r,opt);
	}
	if(mid < r){
		modify(rs(p),mid+1,pr,l,r,opt);
	}
	push_up(p);
	return;
}
int query(int p,int pl,int pr,int opt){
	if(pl == pr){
		return tree[p];
	}
	push_down(p,pl,pr);
	int mid = pl+((pr-pl)>>1);
	if(opt <= mid){
		return query(ls(p),pl,mid,opt);
	}else{
		return query(rs(p),mid+1,pr,opt);
	}
}
vector<int> root;
int ans[400050];
void getans(int now,int fa){
	for(auto i:utd[now]){
		if(i.first == fa){
			continue;
		}
		if(i.second != 0){
			ans[abs(i.second)] = query(1,1,ntot,val[i.first])*i.second/abs(i.second);
		}
		getans(i.first,now);
	}
	return;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= m; i++){
		static int tpa,tpb;
		scanf("%d%d",&tpa,&tpb);
		addedge(tpa,tpb,i);
		addedge(tpb,tpa,-i);
	}
	for(int i = 1; i <= n; i++){
		if(!dfn[i]){
			tarjan(i,0);
//			utd[0].push_back({belong[i],0});
//			utd[belong[i]].push_back({0,0});
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = Last[i]; j; j = Next[j]){
			if(belong[i] != belong[End[j]]){
				utd[belong[i]].push_back({belong[End[j]],id[j]});
//				utd[belong[End[j]]].push_back({belong[i],id[j]});
			}
		}
	}
	for(int i = 1; i <= stot; i++){
		if(!val[i]){
			root.push_back(i);
			dfs1(i,0);
			dfs2(i,i);
		}
	}
//	for(int i = 1; i <= n; i++){
//		printf("%d ",belong[i]);
//	}
//	puts("");
	scanf("%d",&q);
	while(q--){
		static int tp[2],now;
		now = 0;
		scanf("%d%d",&tp[0],&tp[1]);
		tp[0] = belong[tp[0]],tp[1] = belong[tp[1]];
//		printf("%d %d\n",tp[0],tp[1]);
		while(top[tp[0]] != top[tp[1]]){
			if(dep[top[tp[now]]] < dep[top[tp[now^1]]]){
				now ^= 1;
			}
			modify(1,1,ntot,val[top[tp[now]]],val[tp[now]],(now ? -1 : 1));
			tp[now] = top[tp[now]];
			tp[now] = Head[tp[now]];
		}
		if(dep[tp[now]] < dep[tp[now^1]]){
			now ^= 1;
		}
		if(val[tp[now^1]] == val[tp[now]]){
			continue;
		}
//		printf("%d %d\n",val[tp[now^1]],val[tp[now]]);
		modify(1,1,ntot,val[tp[now^1]]+1,val[tp[now]],(now ? -1 : 1));
	}
	for(auto i:root){
		getans(i,0);
	}
//	for(int i = 1; i <= m; i++){
//		printf("%d ",ans[i]);
//	}
//	puts("");
	for(int i = 1; i <= m; i++){
		if(ans[i] == -1){
			putchar('R');
		}else if(ans[i] == 1){
			putchar('L');
		}else{
			putchar('B');
		}
	}
	return 0;
}
2025/1/23 09:07
加载中...