#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n, m;
bool isbridge[maxn], ismulti[maxn];
int tin[maxn], low[maxn], comp[maxn];
int timer = 0;
int binlift[maxn][20];
vector<pair<int,int>> adj[maxn];    // (neighbor, edge_id)
vector<int> bcadj[maxn];            // bridge tree adjacency (components)
int sum1[maxn], sum2[maxn];
int dep[maxn];
pair<int,int> edges[maxn];
map<long long, vector<int>> pos;   // for multi-edges: key = (min << 32) | max
void tarjan(int u, int p) {
    tin[u] = low[u] = ++timer;
    for (auto &[v, id] : adj[u]) {
        if (id == p) continue;
        if (!tin[v]) {
            tarjan(v, id);
            low[u] = min(low[u], low[v]);
            if (low[v] == tin[v] && !ismulti[id]) {
                isbridge[id] = true;
            }
        } else {
            low[u] = min(low[u], tin[v]);
        }
    }
}
void dfs_comp(int u, int c) {
    comp[u] = c;
    for (auto &[v, id] : adj[u]) {
        if (comp[v] || isbridge[id]) continue;
        dfs_comp(v, c);
    }
}
void dfs_bctree(int u, int p) {
    dep[u] = dep[p] + 1;
    binlift[u][0] = p;
    for (int i = 1; i < 20; i++) {
        binlift[u][i] = binlift[binlift[u][i-1]][i-1];
    }
    for (int w : bcadj[u]) {
        if (w == p) continue;
        dfs_bctree(w, u);
    }
}
int lca(int a, int b) {
    if (dep[a] < dep[b]) swap(a, b);
    int diff = dep[a] - dep[b];
    for (int i = 0; i < 20; i++) {
        if (diff & (1 << i)) a = binlift[a][i];
    }
    if (a == b) return a;
    for (int i = 19; i >= 0; i--) {
        if (binlift[a][i] != binlift[b][i]) {
            a = binlift[a][i];
            b = binlift[b][i];
        }
    }
    return binlift[a][0];
}
void dfs_sum(int u, int p) {
    for (int w : bcadj[u]) {
        if (w == p) continue;
        dfs_sum(w, u);
        sum1[u] += sum1[w];
        sum2[u] += sum2[w];
    }
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        adj[i].clear();
        comp[i] = 0;
        tin[i] = 0;
        dep[i] = 0;
        sum1[i] = sum2[i] = 0;
        bcadj[i].clear();
    }
    timer = 0;
    pos.clear();
    for (int i = 1; i <= m; i++) {
        int a, b; cin >> a >> b;
        adj[a].push_back({b, i});
        adj[b].push_back({a, i});
        edges[i] = {a, b};
        long long key = ((long long)min(a,b) << 32) | max(a,b);
        pos[key].push_back(i);
    }
    for (auto &entry : pos) {
        if ((int)entry.second.size() > 1) {
            for (int id : entry.second) {
                ismulti[id] = true;
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!tin[i]) tarjan(i, -1);
    }
    int compCnt = 0;
    for (int i = 1; i <= n; i++) {
        if (!comp[i]) {
            compCnt++;
            dfs_comp(i, compCnt);
        }
    }
    for (int i = 1; i <= compCnt; i++) {
        bcadj[i].clear();
        dep[i] = 0;
        for (int j = 0; j < 20; j++) binlift[i][j] = 0;
    }
    for (int i = 1; i <= m; i++) {
        if (!isbridge[i]) continue;
        int a = comp[edges[i].first];
        int b = comp[edges[i].second];
        bcadj[a].push_back(b);
        bcadj[b].push_back(a);
    }
    for (int i = 1; i <= compCnt; i++) {
        if (!dep[i]) {
            dep[i] = 1;
            dfs_bctree(i, 0);
        }
    }
    int q; cin >> q;
    while (q--) {
        int a, b; cin >> a >> b;
        a = comp[a];
        b = comp[b];
        int c = lca(a, b);
        sum1[a]++;
        sum1[c]--;
        sum2[b]++;
        sum2[c]--;
    }
    for (int i = 1; i <= compCnt; i++) {
        if (dep[i] == 1) dfs_sum(i, 0);
    }
    for (int i = 1; i <= m; i++) {
        if (!isbridge[i]) {
            cout << 'B';
            continue;
        }
        int a = comp[edges[i].first];
        int b = comp[edges[i].second];
        bool swapped = false;
        if (dep[a] < dep[b]) {
            swap(a, b);
            swapped = true;
        }
        bool dir;
        if (sum1[a] > 0) dir = true;   // direction is "up" (from child to parent)
        else if (sum2[a] > 0) dir = false;  // direction is "down" (from parent to child)
        else {
            cout << 'B';
            continue;
        }
        // XOR with swapped because we want direction relative to original edge order
        if (dir ^ swapped) cout << 'R';
        else cout << 'L';
    }
    cout << "\n";
    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... |