#include <bits/stdc++.h>
#define fi first
#define se second
#define sajz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
using namespace std;
typedef long long llf;
typedef unsigned long long ll;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll rnd(ll x, ll y) {return uniform_int_distribution<ll>(x, y)(rng);}
const int N = 2007, Q = 1e5+7;
int n, q, w, h, par[N], sz[N]; string ans[Q];
array<int,3> circle[N], query[Q];
bool res[5][5];
bool check(int i, int j, int x){
auto [x1, y1, r1] = circle[i];
auto [x2, y2, r2] = circle[j];
ll d1 = ll(x1-x2)*(x1-x2) + ll(y1-y2)*(y1-y2);
ll d2 = ll(r1+r2+x)*(r1+r2+x);
return d2 >= d1;
}
int Find(int x) {return (x == par[x] ? x : par[x] = Find(par[x]));}
void Union(int x, int y){
x = Find(x); y = Find(y);
if (x != y){
if (sz[x] < sz[y]) swap(x, y);
par[y] = x;
sz[x] += sz[y];
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> q >> w >> h;
for (int i=1; i<=n; i++){
int x, y, r; cin >> x >> y >> r;
circle[i] = {x, y, r};
}
for (int i=0; i<q; i++){
int r, c; cin >> r >> c;
query[i] = {r, c, i};
}
sort(query, query+q);
//n+1 - gora, n+2 - dol, n+3 - lewo, n+4 - prawo
vector<array<int,3>> edge;
for (int i=1; i<=n; i++) for (int j=i+1; j<=n+4; j++){
if (j <= n){
int l = 0, r = 1e9;
while (l < r){
int mid = (l+r)/2;
if (check(i, j, mid)) r = mid;
else l = mid+1;
}
edge.push_back({l, i, j});
}
else if (j == n+1) edge.push_back({h - circle[i][1] - circle[i][2], i, j});
else if (j == n+2) edge.push_back({circle[i][1] - circle[i][2], i, j});
else if (j == n+3) edge.push_back({circle[i][0] - circle[i][2], i, j});
else if (j == n+4) edge.push_back({w - circle[i][0] - circle[i][2], i, j});
}
sort(all(edge));
//for (auto [d, a, b] : edge) cout << a << ' ' << b << ": " << d << '\n';
for (int i=1; i<=n+4; i++) {par[i] = i; sz[i] = 1;}
for (int i=1; i<=4; i++) for (int j=1; j<=4; j++) res[i][j] = true;
int j = -1;
for (int i=0; i<q; i++){
auto [r, c, ind] = query[i];
//cout << i << ' ' << r << " -----------\n";
while (j+1 < sajz(edge) && edge[j+1][0] < 2*r){
j++;
auto [d, a, b] = edge[j];
Union(a, b);
//cout << d << ' ' << a << ' ' << b << '\n';
}
//for (int k=1; k<=n+4; k++) cout << k << ": " << Find(k) << '\n';
if (Find(n+2) == Find(n+3)){
for (int k=1; k<=4; k++) if (k != 1) res[1][k] = res[k][1] = false;
}
if (Find(n+2) == Find(n+4)){
for (int k=1; k<=4; k++) if (k != 2) res[2][k] = res[k][2] = false;
}
if (Find(n+1) == Find(n+4)){
for (int k=1; k<=4; k++) if (k != 3) res[3][k] = res[k][3] = false;
}
if (Find(n+1) == Find(n+3)){
for (int k=1; k<=4; k++) if (k != 4) res[4][k] = res[k][4] = false;
}
if (Find(n+1) == Find(n+2)){
res[1][2] = res[1][3] = res[4][2] = res[4][3] = false;
res[2][1] = res[2][1] = res[3][4] = res[3][4] = false;
}
if (Find(n+3) == Find(n+4)){
res[1][3] = res[1][4] = res[2][3] = res[2][4] = false;
res[3][1] = res[3][2] = res[4][1] = res[4][2] = false;
}
//for (int k=1; k<=4; k++){
//cout << k << ": ";
//for (int k2=1; k2<=4; k2++) if (res[k][k2]) cout << ele[k2] << ' '; cout << '\n';
//}
for (int k=1; k<=4; k++) if (res[c][k]) ans[ind] += k+'0';
}
for (int i=0; i<q; i++) cout << ans[i] << '\n';
return 0;
}
/*
5 3
16 11
11 8 1
6 10 1
7 3 2
10 4 1
15 5 1
1 1
2 2
2 1
*/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |