QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#565864 | #9319. Bull Farm | ucup-team1001 | WA | 0ms | 3648kb | C++23 | 6.7kb | 2024-09-15 22:26:31 | 2024-09-15 22:26:32 |
Judging History
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();
}
}
Details
Tip: Click on the bar to expand more detailed information
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'