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;
}