QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#349505 | #8315. Candy Ads | hos_lyric | WA | 0ms | 4036kb | C++14 | 6.9kb | 2024-03-10 02:29:53 | 2024-03-10 02:29:53 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
// get0(u): should return a neighbor of u and remove it (or -1).
// get1(u): the same for reversed edge
template <class Get0, class Get1> struct SccDyn {
int n;
const Get0 get0;
const Get1 get1;
int l;
vector<int> ids;
int operator[](int u) const { return ids[u]; }
SccDyn(int n_, Get0 get0_, Get1 get1_) : n(n_), get0(get0_), get1(get1_) {
ids.assign(n, 0);
us.clear();
for (int u = 0; u < n; ++u) dfs0(u);
l = 0;
for (int j = n; --j >= 0; ) if (!~ids[us[j]]) { dfs1(us[j]); ++l; }
}
vector<int> us;
void dfs0(int u) {
if (!ids[u]) {
ids[u] = -1;
for (; ; ) {
const int v = get0(u);
if (!~v) break;
dfs0(v);
}
us.push_back(u);
}
}
void dfs1(int u) {
if (!~ids[u]) {
ids[u] = l;
for (; ; ) {
const int v = get1(u);
if (!~v) break;
dfs1(v);
}
}
}
vector<vector<int>> group() const {
assert(~l);
vector<vector<int>> uss(l);
for (int u = 0; u < n; ++u) uss[ids[u]].push_back(u);
return uss;
}
}; // SccDyn
template <class Get0, class Get1>
SccDyn<Get0, Get1> sccDyn(int n, Get0 get0, Get1 get1) {
return SccDyn<Get0, Get1>(n, get0, get1);
}
template <class Get> auto sccDyn(int n, Get get) {
return sccDyn(
n,
[&](int u) -> int { return get(0, u); },
[&](int u) -> int { return get(1, u); }
);
}
////////////////////////////////////////////////////////////////////////////////
int N, W, H;
int P[50010][4];
int M;
vector<int> A, B;
struct Kdt {
int nn;
vector<int> us, os;
struct Node {
int t;
int l, r;
int mn[4], mx[4];
};
vector<Node> nodes;
void build() {
us.resize(N);
for (int u = 0; u < N; ++u) us[u] = u;
nn = 0;
nodes.resize(2 * N - 1);
os.assign(N, -1);
buildRec(0, N, 0);
}
int buildRec(int jL, int jR, int dir) {
const int o = nn++;
Node &node = nodes[o];
for (int d = 0; d < 4; ++d) node.mn[d] = node.mx[d] = P[us[jL]][d];
if (jL + 1 == jR) {
os[us[jL]] = o;
node.t = us[jL];
node.l = node.r = -1;
} else {
for (int j = jL + 1; j < jR; ++j) {
for (int d = 0; d < 4; ++d) {
chmin(node.mn[d], P[us[j]][d]);
chmax(node.mx[d], P[us[j]][d]);
}
}
const int jMid = jL + (jR - jL) / 2;
std::nth_element(us.begin() + jL, us.begin() + jMid, us.begin() + jR,
[&](int u0, int u1) -> bool {
return (P[u0][dir] < P[u1][dir]);
});
node.l = buildRec(jL, jMid, (dir + 1) & 3);
node.r = buildRec(jMid, jR, (dir + 1) & 3);
node.t = max(nodes[node.l].t, nodes[node.r].t);
}
return o;
}
/*
p[0] <= r
l <= p[1]
a <= p[2] <= b
c <= p[3] <= d
*/
int take(int r, int l, int a, int b, int c, int d) {
return takeRec(0, r, l, a, b, c, d);
}
int takeRec(int o, int r, int l, int a, int b, int c, int d) {
Node &node = nodes[o];
if (!~node.t) {
return -1;
}
if (!( node.mn[0] <= r
&& l <= node.mx[1]
&& a <= node.mx[2] && node.mn[2] <= b
&& c <= node.mx[3] && node.mn[3] <= d)) {
return -1;
}
if (!~node.l) {
const int u = node.t;
node.t = -1;
return u;
}
int u = takeRec(node.l, r, l, a, b, c, d);
if (!~u) {
u = takeRec(node.r, r, l, a, b, c, d);
}
node.t = max(nodes[node.l].t, nodes[node.r].t);
return u;
}
void restore(int u) {
restoreRec(0, u);
}
void restoreRec(int o, int u) {
Node &node = nodes[o];
if (!~node.l) {
node.t = u;
return;
}
restoreRec((os[u] < node.r) ? node.l : node.r, u);
node.t = max(nodes[node.l].t, nodes[node.r].t);
}
};
int main() {
for (; ~scanf("%d%d%d", &N, &W, &H); ) {
for (int u = 0; u < N; ++u) for (int d = 0; d < 4; ++d) {
scanf("%d", &P[u][d]);
}
scanf("%d", &M);
A.resize(M);
B.resize(M);
for (int i = 0; i < M; ++i) {
scanf("%d%d", &A[i], &B[i]);
--A[i];
--B[i];
}
Kdt kdt[2];
vector<vector<int>> graph[2];
for (int s = 0; s < 2; ++s) {
kdt[s].build();
graph[s].assign(N, {});
for (int i = 0; i < M; ++i) {
graph[s][A[i]].push_back(B[i]);
graph[s][B[i]].push_back(A[i]);
}
}
const auto scc = sccDyn(N << 1, [&](int s, int uu) -> int {
const int u = uu >> 1;
if ((uu & 1) != s) {
// s = 0: u ==> not(v)
int v = kdt[s].take(P[u][1], P[u][0], P[u][2] - W + 1, P[u][2], P[u][3] - H + 1, P[u][3]);
if (!~v) return -1;
if (u == v) {
v = kdt[s].take(P[u][1], P[u][0], P[u][2] - W + 1, P[u][2], P[u][3] - H + 1, P[u][3]);
kdt[s].restore(u);
if (!~v) return -1;
}
// cerr<<__LINE__<<": [get] "<<s<<" "<<u<<" "<<v<<"; "<<uu<<" "<<(v<<1|s)<<endl;
return v << 1 | s;
} else {
// s = 0: not(u) ==> v
if (!graph[s][u].size()) return -1;
const int v = graph[s][u].back();
graph[s][u].pop_back();
// cerr<<__LINE__<<": [get] "<<s<<" "<<u<<" "<<v<<"; "<<uu<<" "<<(v<<1|(s^1))<<endl;
return v << 1 | (s ^ 1);
}
});
// cerr<<"scc = "<<scc.ids<<endl;
bool ok = true;
string ans(N, '?');
for (int u = 0; u < N; ++u) {
ok = ok && (scc[u << 1] != scc[u << 1 | 1]);
ans[u] = (scc[u << 1] < scc[u << 1 | 1]) ? '1' : '0';
}
if (ok) {
puts("Yes");
puts(ans.c_str());
} else {
puts("No");
}
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3804kb
input:
2 2 2 1 2 1 1 2 3 2 2 1 1 2
output:
Yes 01
result:
ok accepted
Test #2:
score: 0
Accepted
time: 0ms
memory: 3752kb
input:
3 2 2 1 2 1 1 1 3 1 2 2 3 2 2 3 1 2 2 3 1 3
output:
No
result:
ok accepted
Test #3:
score: 0
Accepted
time: 0ms
memory: 3728kb
input:
10 3 3 2 3 7 10 1 3 9 6 3 5 2 1 4 5 8 9 4 7 1 7 3 4 4 4 6 8 9 5 1 3 6 7 2 5 7 4 6 9 9 9 10 9 1 6 2 8 5 9 5 10 4 5 1 3 2 10 9 9 5 8 2
output:
Yes 1010110111
result:
ok accepted
Test #4:
score: 0
Accepted
time: 0ms
memory: 3736kb
input:
10 2 4 2 5 4 8 8 10 6 3 1 3 7 3 8 10 7 9 1 2 2 6 3 6 9 2 4 7 2 10 8 9 7 4 8 9 7 1 1 2 9 8 8 2 4 6 5 1 4 6 9 9 5 6 3 6 8 8 2
output:
Yes 0001110100
result:
ok accepted
Test #5:
score: -100
Wrong Answer
time: 0ms
memory: 4036kb
input:
10 4 3 8 9 8 8 4 5 6 8 8 9 3 2 5 7 10 6 6 7 7 9 3 5 7 3 9 10 9 4 4 7 9 2 9 10 8 2 3 5 1 8 14 8 10 10 1 1 10 6 4 2 3 9 6 8 6 5 2 9 8 1 9 10 7 1 6 10 8 3 6
output:
Yes 1010110111
result:
wrong answer overlap