This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<ll, ll>
#define pli pair<ll, pii>
#define fi first
#define se second
const ll MX = 3e5 + 10;
const ll INF = 1e18;
ll N, X[MX], Y[MX], direction[MX];
// Right, Down, Left, Up
map<ll, vector<pii>> vert[4], hori[4], incd[4], decd[4];
ll dist[MX * 3]; bool colored[MX], vis[MX * 3];
vector<pii> adj[MX * 3];
// node, weight
void buildEdge(vector<pii>& v, ll inc, ll dir){ // dir 0 line, 1 clockwise, 2 counterclockwise
if(inc == 1){
for(ll i = 1; i < v.size(); i++){
ll w = (v[i].fi - v[i - 1].fi) / (dir == 0 ? 2ll : 1ll);
adj[(ll) 3 * v[i - 1].se + dir].push_back({(ll) 3 * v[i].se + dir, w});
}
}else{
for(ll i = v.size() - 1; i > 0; i--){
ll w = (v[i].fi - v[i - 1].fi) / (dir == 0 ? 2ll : 1ll);
adj[(ll) 3 * v[i].se + dir].push_back({(ll) 3 * v[i - 1].se + dir, w});
}
}
}
ll absol(ll x){
return x > 0 ? x : -x;
}
pii trav(vector<pii>& v, ll node, ll d, ll dir){
ll idx = lower_bound(v.begin(), v.end(), make_pair(d, (ll) -1)) - v.begin();
if(idx == v.size()) return make_pair(-1, 0);
ll nxt = v[idx].se, mdist;
mdist = (absol(X[node] - X[nxt]) + absol(Y[node] - Y[nxt])) / 2;
return {nxt * 3 + dir, mdist};
}
pii dtrav(vector<pii>& v, ll node, ll d, ll dir){
ll idx = lower_bound(v.begin(), v.end(), make_pair(d + 1, (ll) -1)) - v.begin() - 1;
if(idx == -1) return make_pair(-1, 0);
ll nxt = v[idx].se, mdist;
mdist = (absol(X[node] - X[nxt]) + absol(Y[node] - Y[nxt])) / 2;
return {nxt * 3 + dir, mdist};
}
ll solve(){
memset(vis, 0, sizeof vis);
for(ll i = 0; i < 3 * MX; i++){
adj[i].clear();
dist[i] = INF;
if(i < MX) colored[i] = false;
}
direction[0] = 0;
for(ll i = 1; i < N; i++){
ll _x = X[i] / 2, _y = Y[i] / 2;
if(_x < 0 && (_y <= 0 ? -_y <= -_x : _y <= -_x)) direction[i] = 0;
else if(_y > 0 && (_x <= 0 ? -_x <= _y - 1 : _x <= _y)) direction[i] = 1;
else if(_x > 0 && (_y <= 0 ? -_y <= _x - 1 : _y <= _x - 1)) direction[i] = 2;
else if(_y < 0 && (_x <= 0 ? -_x <= -_y - 1 : _x <= -_y)) direction[i] = 3;
else assert(false);
}
for(ll d = 0; d < 4; d++){
vert[d].clear(), hori[d].clear(), incd[d].clear(), decd[d].clear();
}
for(ll i = 0; i < N; i++){
vert[direction[i]][X[i]].push_back({Y[i], i});
hori[direction[i]][Y[i]].push_back({X[i], i});
incd[direction[i]][X[i] - Y[i]].push_back({X[i], i});
decd[direction[i]][X[i] + Y[i]].push_back({X[i], i});
}
for(ll d = 0; d < 4; d++){
for(auto& x : vert[d]) sort(x.se.begin(), x.se.end());
for(auto& x : hori[d]) sort(x.se.begin(), x.se.end());
for(auto& x : incd[d]) sort(x.se.begin(), x.se.end());
for(auto& x : decd[d]) sort(x.se.begin(), x.se.end());
}
// Right, Down, Left, Up
{
for(auto& x : hori[0]) buildEdge(x.se, 0, 0);
for(auto& x : vert[1]) buildEdge(x.se, 1, 0);
for(auto& x : hori[2]) buildEdge(x.se, 1, 0);
for(auto& x : vert[3]) buildEdge(x.se, 0, 0);
}
{
for(auto& x : incd[0]) buildEdge(x.se, 0, 2);
for(auto& x : incd[1]) buildEdge(x.se, 1, 1);
for(auto& x : incd[2]) buildEdge(x.se, 1, 2);
for(auto& x : incd[3]) buildEdge(x.se, 0, 1);
}
{
for(auto& x : decd[0]) buildEdge(x.se, 0, 1);
for(auto& x : decd[1]) buildEdge(x.se, 0, 2);
for(auto& x : decd[2]) buildEdge(x.se, 1, 1);
for(auto& x : decd[3]) buildEdge(x.se, 1, 2);
}
priority_queue<pii, vector<pii>, greater<pii>> pq;
pq.push({0, 0});
dist[0] = 0;
ll cnt = 0;
while(!pq.empty()){
// place-holder node
ll cd = pq.top().fi; ll pd = pq.top().se; pq.pop();
if(!vis[pd]){ // Reachable edge
vis[pd] = true;
for(auto nxt : adj[pd]){
ll nd = cd + nxt.se;
if(dist[nxt.fi] > nd){
dist[nxt.fi] = nd;
pq.push({dist[nxt.fi], nxt.fi});
}
}
}
// Right, Down, Left, Up
ll node = pd / 3;
if(!colored[node]){ // isColored
// find collision
pii nxt = {-1, 0};
if(direction[node] == 0){
nxt = trav(hori[2][Y[node]], node, X[node] + (ll) 2 * dist[pd], 0);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = trav(incd[1][X[node] - Y[node]], node, X[node] + dist[pd], 1);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = trav(decd[3][X[node] + Y[node]], node, X[node] + dist[pd], 2);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
}else if(direction[node] == 1){
nxt = dtrav(vert[3][X[node]], node, Y[node] - (ll) 2 * dist[pd], 0);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = trav(decd[2][X[node] + Y[node]], node, X[node] + dist[pd], 1);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = dtrav(incd[0][X[node] - Y[node]], node, X[node] - dist[pd], 2);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
}else if(direction[node] == 2){
nxt = dtrav(hori[0][Y[node]], node, X[node] - (ll) 2 * dist[pd], 0);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = dtrav(incd[3][X[node] - Y[node]], node, X[node] - dist[pd], 1);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = dtrav(decd[1][X[node] + Y[node]], node, X[node] - dist[pd], 2);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
}else if(direction[node] == 3){
nxt = trav(vert[1][X[node]], node, Y[node] + (ll) 2 * dist[pd], 0);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = dtrav(decd[0][X[node] + Y[node]], node, X[node] - dist[pd], 1);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
nxt = trav(incd[2][X[node] - Y[node]], node, X[node] + dist[pd], 2);
if(nxt.fi != -1 && dist[nxt.fi] > nxt.se){
dist[nxt.fi] = nxt.se; pq.push({dist[nxt.fi], nxt.fi});
}
}
colored[node] = true;
cnt++;
}
}
return cnt;
}
void rotate(){
for(ll i = 0; i < N; i++){
swap(X[i], Y[i]);
Y[i] = -Y[i];
}
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N;
for(ll i = 0; i < N; i++){
cin >> X[i] >> Y[i]; X[i] <<= 1, Y[i] <<= 1;
if(i != 0) X[i] -= X[0], Y[i] -= Y[0];
}
X[0] = Y[0] = 0;
ll ans = 0;
for(ll i = 0; i < 4; i++){
ans = max(ans, solve());
rotate();
}
cout << ans << '\n';
}
Compilation message (stderr)
fever.cpp: In function 'void buildEdge(std::vector<std::pair<long long int, long long int> >&, long long int, long long int)':
fever.cpp:25:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
25 | for(ll i = 1; i < v.size(); i++){
| ~~^~~~~~~~~~
fever.cpp: In function 'std::pair<long long int, long long int> trav(std::vector<std::pair<long long int, long long int> >&, long long int, long long int, long long int)':
fever.cpp:43:9: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
43 | if(idx == v.size()) return make_pair(-1, 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... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |