QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#565864#9319. Bull Farmucup-team1001WA 0ms3648kbC++236.7kb2024-09-15 22:26:312024-09-15 22:26:32

Judging History

你现在查看的是最新测评结果

  • [2024-09-15 22:26:32]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3648kb
  • [2024-09-15 22:26:31]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;


const int mod = 998244353;

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    os << "{";
    for (const T &x: v) {
        os << x << " ";
    }
    os << "}";
    return os;
}


using i64 = long long;


class Tarjan {
    int n;
    vector<vector<int>> G;
    vector<vector<int>> go;
    vector<int> scc;
    vector<int> dfn, up, du;
public:

    Tarjan(int _n) : n(_n), G(n + 1), scc(n + 1) {
        iota(scc.begin(), scc.end(), 0);
    }

    void init() {
        int _n = n;
        // tarjan 更新 scc ys n
        {
            vector<int> _dfn(n + 1), _low(n + 1);
            vector<int> _scc(n + 1);
            vector<int> _ys(n + 1);
            vector<int> _stk(n + 1);
            int _top = 0;
            int _scc_cnt = 1;
            int _dfn_cnt = 0;
            function<void(int)> tarjan = [&](int u) {
                _dfn[u] = _low[u] = ++_dfn_cnt;
                _stk[++_top] = u;
                for (int v: G[u]) {
                    if (!_dfn[v]) {
                        tarjan(v);
                        _low[u] = min(_low[u], _low[v]);
                    } else if (!_scc[v]) {
                        _low[u] = min(_low[u], _dfn[v]);
                    }
                }
                if (_dfn[u] == _low[u]) {
                    int v;
                    do {
                        v = _stk[_top--];
                        _scc[v] = _scc_cnt;
                    } while (v != u);
                    _scc_cnt++;
                }
            };
            for (int i = 1; i <= _n; i++) {
                if (!_dfn[i]) {
                    tarjan(i);
                }
            }
            int nn = scc.size() - 1;
            for (int i = 1; i <= nn; i++) {
                scc[i] = _scc[scc[i]];
            }
//            cerr << "scc " << scc << endl;

            n = _scc_cnt - 1;
            // 更新图
            {
                vector<vector<int>> _G(n + 1);

                vector<int> _du(n + 1);
                for (int i = 1; i <= _n; i++) {
                    for (int j: G[i]) {
                        if (_scc[i] != _scc[j]) {
                            _G[_scc[i]].push_back(_scc[j]);
                            _du[_scc[j]]++;
                        }
                    }
                }
                G = _G;
//                cerr << "G " << G << endl;
                du = _du;
            }
        }
        // 更新dfn up
        {
            vector<vector<int>> _go(n + 1, vector<int>(n + 1));
            function<void(int, int)> dfs = [&](int u, int v) {
                _go[u][v] = 1;
                for (int i: G[v]) {
                    dfs(u, i);
                }
            };
            for (int i = 1; i <= n; i++) {
                dfs(i, i);
            }
            go = _go;
        }

    }

    bool can_reach(int u, int v) {
        return go[u][v];
    }
//    }

    void add_edge(int u, int v) {
        if (scc[u] != scc[v]) {
//            cerr << "add edge " << u << " " << v << endl;
            G[scc[u]].push_back(scc[v]);
        }
    }


};
//000000010100000010010000100110...0010011000001101000010001111000',
//000000010100000010010000100110...0010011000000001000010001110000

int decreace(char a, char b) {
    return (a - 48) * 50 + (b - 48);
}

class Query {
public:
    int from, to, time, idx;

    Query(int from, int to, int time, int idx) : from(from), to(to), time(time), idx(idx) {}

    bool operator<(const Query &q) const {
        return time < q.time;
    }

};

// 解密字符串
vector<int> decrypt(const string &s) {
    vector<int> res = {0};
    for (int i = 0; i < s.size(); i += 2) {
        res.push_back(decreace(s[i], s[i + 1]));
    }
    return res;
}


void solve() {
    int n, l, q;
    cin >> n >> l >> q;
    vector<string> s(l + 1);
    for (int i = 1; i <= l; i++) {
        cin >> s[i];
    }
    vector<Query> qs;
    for (int i = 0; i < q; i++) {
        string sa;
        cin >> sa;
        auto v = decrypt(sa);
        qs.emplace_back(v[1], v[2], v[3], i);
    }
    sort(qs.begin(), qs.end());
    int now = 0;
    vector<int> ans(q);
    Tarjan tarjan(n);
    auto modify = [&](int _i) -> bool {
        auto v = decrypt(s[_i]);
//        cerr << v << endl;
        vector<int> du(n + 1);
        for (int i = 1; i <= n; i++) {
            du[v[i]]++;
        }
        //找到入度为0的个数
        int cnt = 0;
        int cnt_id;
        for (int i = 1; i <= n; i++) {
            if (du[i] == 0) {
                cnt++;
                cnt_id = i;
            }
        }
        if (cnt == 0) {
            for (int i = 1; i <= n; i++) {
//                cerr << i << " " << v[i] << endl;
                tarjan.add_edge(i, v[i]);
            }
            return true;
        } else if (cnt == 1) {
            int i = cnt_id;
            while (du[i] == 0) {
                if (du[v[i]] == 2) {
                    tarjan.add_edge(i, cnt_id);
                }
                i = v[i];
                du[i]--;

            }
            int j = v[i];
            while (v[j] != i) {
//                tarjan.add_edge(j, v[j]);
                j = v[j];
            }
            tarjan.add_edge(j, cnt_id);
            return true;
        }
        return false;
    };
    tarjan.init();
    for (auto &qq: qs) {
        bool f = false;
        while (now < qq.time) {
            now++;
            f |= modify(now);
//            if(modify(now)){
//                break;
//            }
//            modify(now);
//            tarjan.init();
        }
        if (f) {
            tarjan.init();
        }
        ans[qq.idx] = tarjan.can_reach(qq.from, qq.to);
//        cerr << qq.idx << " " << qq.from << " " << qq.to << " " << qq.time << " " << ans[qq.idx] << endl;
    }
    for (int i = 0; i < q; i++) {
        cout << ans[i];

//        cout << (ans[i] ? "YES" : "NO") << endl;
    }
    cout << endl;

}
//1
//4 1 1
//02030403
//020101
//4 1 10
//02030403
//010201
//020301
//030401
//040301
//040101
//020101
//010201
//020301
//030401
//040301
//040101
//020101
//
//010201
//020301
//030401
//040301
//040101
//020101
//010201
//020301
//030401
//040301
//040101
//020101

//1
//5 5 2
//0405020501
//0404050302
//0105050105
//0304010205
//0402030205
//040200
//010203
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
}

详细

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3648kb

input:

2
5 2 4
0305040201
0404040404
030300
020500
050102
020501
6 2 4
030603010601
010203060504
030202
060402
050602
060401

output:

1010
0000

result:

wrong answer 1st lines differ - expected: '1011', found: '1010'