#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define BIT(x , i) (((x) >> (i)) & 1)
#define MASK(i) (1ll << (i))
#define pb push_back
#define LOG 17
#define endl '\n'
template <class X , class Y>
    bool minimize(X& x , const Y& y) {
        if(x > y) {
            x = y ;
            return true ;
        }
        return false ;
    }
template <class X , class Y>
    bool maximize(X& x , const Y& y) {
        if(x < y) {
            x = y ;
            return true ;
        }
        return false ;
    }
const int MAXN = 1e5 + 2 ;
struct AKARI_KITO {
    int node , id ; 
    bool ahihi ;
} ;
vector <int> adj[MAXN] ; vector <pair <int , int>> e ; vector <AKARI_KITO> tree[MAXN] ; vector <bool> used(MAXN , false) , isBridge(MAXN , false) ;
int numNode , numEdge , cnt = 0 , numQueries , low[MAXN] , num[MAXN] , compID[MAXN] , par[MAXN][LOG + 1] , dep[MAXN] , goDown[MAXN] , goUp[MAXN] , leftNode[MAXN] , rightNode[MAXN] ;
void loadGraph(void) {
    cin >> numNode >> numEdge ;
    for(int i = 0 ; i < numEdge ; ++i) {
        int u , v ; cin >> u >> v ;
        leftNode[i] = u ; rightNode[i] = v ;
        adj[u].pb(i) ; adj[v].pb(i) ;
        e.pb({u , v}) ;
    }
    cin >> numQueries ;
}
void getBridge(int u) {
    low[u] = num[u] = ++cnt ;
    for(int id : adj[u]) if(!used[id]) {
        used[id] = true ;
        int v = e[id].first ^ e[id].second ^ u ;
        if(num[v] == 0) {
            getBridge(v) , minimize(low[u] , low[v]) ;
            if(low[v] > num[u]) isBridge[id] = true ;
        }
        else minimize(low[u] , num[v]) ;
    }
}
int hihi = 0 ;
void compress(void) {
    queue <int> q ;
    vector <bool> vis(numNode + 1 , false) ;
    for(int i = 1 ; i <= numNode ; ++i) if(vis[i] == false) {
        ++hihi ;
        vis[i] = true ;
        q.push(i) ;
        while(!q.empty()) {
            int u = q.front() ; q.pop() ;
            compID[u] = hihi ;
            for(int id : adj[u]) {
                if(isBridge[id] == true) continue ;
                int v = e[id].first ^ e[id].second ^ u ;
                if(vis[v] == false) vis[v] = true , q.push(v) ;
            }
        }
    }
    for(int i = 0 ; i < numEdge ; ++i) if(isBridge[i] == true) {
        int u = e[i].first , v = e[i].second ;
        bool ok1 = false , ok2 = false ;
        if(leftNode[i] == u && rightNode[i] == v) ok1 = true ;
        else ok2 = true ;
        tree[ compID[u] ].pb({compID[v] , i , ok1}) ; tree[ compID[v] ].pb({compID[u] , i , ok2}) ;
    }
}
void dfs(int u) {
    for(AKARI_KITO id : tree[u]) {
        int v = id.node ;
        if(v != par[u][0]) {
            par[v][0] = u ;
            dep[v] = dep[u] + 1 ;
            dfs(v) ;
        }
    }
}
void buildLCK(void) {
    for(int j = 1 ; j <= LOG ; ++j) for(int i = 1 ; i <= numNode ; ++i) par[i][j] = par[par[i][j - 1]][j - 1] ;
}
int LCK(int u , int v) {
    if(dep[u] < dep[v]) swap(u , v) ;
    int h = dep[u] - dep[v] ;
    for(int i = 0 ; i <= LOG ; ++i) if(BIT(h , i)) u = par[u][i] ;
    if(u == v) return u ;
    for(int i = LOG ; i >= 0 ; --i) if(par[u][i] != par[v][i]) u = par[u][i] , v = par[v][i] ;
    return par[u][0] ;
}
vector <char> res(MAXN) ;
vector <bool> marked(MAXN , false) ;
void rieTakahashi(int u) {
    marked[u] = true ;
    for(AKARI_KITO id : tree[u]) {
        int v = id.node , edgeID = id.id ;
        bool ok = id.ahihi ;
        if(v != par[u][0]) {
            rieTakahashi(v) ;
            goUp[u] += goUp[v] ;
            goDown[u] += goDown[v] ;
            // ok == true -> u = leftNode , v = rightNode 
            // ok == false -> u = rightNode , v = leftNode 
            if(goUp[v] > 0) res[edgeID] = (ok == true ? 'L' : 'R') ;
            else if(goDown[v] > 0) res[edgeID] = (ok == true ? 'R' : 'L') ;
            else res[edgeID] = 'B' ;
        }
    }
}
void process(void) {
    for(int i = 1 ; i <= numQueries ; ++i) {
        int u , v ; cin >> u >> v ;
        int LCA = LCK(compID[u] , compID[v]) ;
        ++goUp[compID[u]] , ++goDown[compID[v]] ;
        --goUp[LCA] , --goDown[LCA] ;
    }
    for(int i = 1 ; i <= hihi ; ++i) if(marked[i] == false) rieTakahashi(i) ;
    for(int i = 0 ; i < numEdge ; ++i) {
        if(isBridge[i] == false) cout << 'B' ;
        else cout << res[i] ;
    }
}
int32_t main(void) {
    ios_base :: sync_with_stdio(false) ;
    cout.tie(nullptr) ;
    cin.tie(nullptr) ;
    loadGraph() ;
    for(int i = 1 ; i <= numNode ; ++i) if(num[i] == 0) getBridge(i) ;
    compress() ;
    for(int i = 1 ; i <= hihi ; ++i) if(dep[i] == 0) dfs(i) ;
    buildLCK() ;
    process() ;
    return 0 ;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |