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;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pii;
#define fi first
#define se second
#define mp make_pair
#define fastIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int N = (int)1e5 + 100;
ll H[N], W[N];
int dir[4][2] = {{0,+1},{0,-1},{+1,0},{-1,0}};
int n;
int sol = 0;
struct E{
ll val;
ll sec;
int idx;
bool operator<(const E &e) const {
if(val == e.val)
return sec < e.sec;
return val < e.val;
}
};
vector<E> vv[4][4];
struct node{
pii low_val;
pii sol;
ll lazy;
};
struct segment_tree{
vector<ll> vls;
vector<node> pap;
int m;
void build(int node, int cl, int cr){
pap[node].lazy = -(ll)1e18;
if(cl == cr){
pap[node].low_val = mp(vls[cl], cl);
pap[node].sol = mp((ll)1e18, cl);
return;
}
int mid = (cl + cr) / 2;
build(node * 2, cl, mid);
build(node * 2 + 1, mid + 1, cr);
pap[node].low_val = min(pap[node*2].low_val, pap[node*2+1].low_val);
pap[node].sol = min(pap[node*2].sol, pap[node*2+1].sol);
}
void init(vector<E> sha){
vls.clear();
pap.clear();
m = sha.size();
if(m == 0) return;
pap.resize(4 * m + 16);
for(int i = 0 ; i < m ; i ++ ){
vls.push_back(sha[i].sec);
}
build(1, 0, m - 1);
}
void push(int node, int cl, int cr){
pap[node].sol = min(pap[node].sol, mp(pap[node].low_val.fi - pap[node].lazy,pap[node].low_val.se));
if(cl != cr){
pap[node*2].lazy = max(pap[node*2].lazy, pap[node].lazy);
pap[node*2+1].lazy = max(pap[node*2+1].lazy, pap[node].lazy);
}
}
void update(int node, int cl, int cr, int tl, int tr, ll vv){
push(node, cl, cr);
if(cr < tl || cl > tr){
return;
}
if(cl >= tl && cr <= tr){
pap[node].lazy = max(pap[node].lazy, vv);
push(node, cl, cr);
return;
}
int mid = (cl + cr) / 2;
update(node * 2, cl, mid, tl, tr, vv);
update(node * 2 + 1, mid + 1, cr, tl, tr, vv);
pap[node].sol = min(pap[node * 2].sol, pap[node * 2 + 1].sol);
}
void clean(int node, int cl, int cr, int id){
push(node, cl, cr);
if(cl == cr){
pap[node].low_val = mp((ll)1e18, id);
pap[node].sol = mp((ll)1e18, id);
return;
}
int mid = (cl + cr) / 2;
if(mid >= id)
clean(node * 2, cl, mid, id);
else
clean(node * 2 + 1, mid + 1, cr, id);
pap[node].low_val = min(pap[node*2].low_val, pap[node*2+1].low_val);
pap[node].sol = min(pap[node * 2].sol, pap[node * 2 + 1].sol);
pap[node].sol = min(pap[node].sol, mp(pap[node].low_val.fi - pap[node].lazy, pap[node].low_val.se));
}
};
segment_tree opt[4][4];
int go[N];
ll low[N];
int solve(){
go[0] = 0;
for(int i = 2; i <= n; i ++ ){
if(abs(H[i]) == abs(W[i])){
if(W[i] < 0) go[i] = 0;
else {
if(H[i] > 0)
go[i] = 3;
else
go[i] = 2;
}
}
else{
if(abs(H[i]) > abs(W[i])){
if(H[i] > 0)
go[i] = 3;
else
go[i] = 2;
}
else{
if(W[i] > 0){
go[i] = 1;
}
else{
go[i] = 0;
}
}
}
low[i]=(ll)1e18;
}
low[1]=0;
for(int p = 0 ; p < 4; p ++ ){
for(int q = 0; q < 4; q ++ ){
vv[p][q].clear();
}
}
E cur;
ll AH, AW;
for(int p = 0 ; p < 4; p ++ ){
for(int i = 1; i <= n; i ++ ){
if(go[i] != p){
AH = dir[p][0] - dir[go[i]][0];
AW = dir[p][1] - dir[go[i]][1];
cur.val = AW * 1ll * H[i] - AH * 1ll * W[i];
if(AH != 0) cur.sec = H[i] / AH;
else cur.sec = W[i] / AW;
cur.idx = i;
vv[p][go[i]].push_back(cur);
}
}
}
for(int p = 0 ; p < 4; p ++ ){
for(int q = 0; q < 4; q ++ ){
sort(vv[p][q].begin(), vv[p][q].end());
opt[p][q].init(vv[p][q]);
}
}
int cnt = 0;
int id = -1;
ll nw;
int cid;
ll add;
int lf, rf;
int nex;
int iq;
while(1){
if(cnt == 0){
id = 1;
low[id] = 0;
}
else{
nw = (ll)2e18;
cid = -1;
for(int p = 0; p < 4; p ++ ){
for(int q = 0; q < 4; q ++ ){
if(p == q || opt[p][q].m == 0) continue;
if(opt[p][q].pap[1].sol.fi < nw){
nw = opt[p][q].pap[1].sol.fi;
cid = vv[p][q][opt[p][q].pap[1].sol.se].idx;
}
}
}
if(nw > (ll)1e14) break;
id = cid;
low[id] = nw;
}
cnt ++ ;
for(int p = 0 ; p < 4; p ++ ){
if(p == go[id]) continue;
AH = dir[p][0] - dir[go[id]][0];
AW = dir[p][1] - dir[go[id]][1];
cur.val = AW * H[id] - AH * W[id];
if(AH != 0) cur.sec = H[id] / AH;
else cur.sec = W[id] / AW;
cur.idx = -1;
iq = lower_bound(vv[p][go[id]].begin(), vv[p][go[id]].end(), cur) - vv[p][go[id]].begin();
opt[p][go[id]].clean(1, 0, opt[p][go[id]].m - 1, iq);
}
for(int nx = 0; nx < 4; nx ++ ){
if(nx == go[id] || vv[go[id]][nx].empty()) continue;
AH = dir[go[id]][0] - dir[nx][0];
AW = dir[go[id]][1] - dir[nx][1];
cur.val = AW * H[id] - AH * W[id];
cur.sec = low[id];
if(AH != 0) add = H[id] / AH;
else add = W[id] / AW;
cur.sec += add;
lf = lower_bound(vv[go[id]][nx].begin(), vv[go[id]][nx].end(), cur) - vv[go[id]][nx].begin();
if(lf < vv[go[id]][nx].size() && vv[go[id]][nx][lf].val == cur.val){
rf = lf;
for(int lg = 17; lg >= 0 ; lg -- ){
nex = rf + (1 << lg);
if(nex < vv[go[id]][nx].size() && vv[go[id]][nx][nex].val == cur.val){
rf = nex;
}
}
opt[go[id]][nx].update(1, 0, opt[go[id]][nx].m - 1, lf, rf, add);
}
}
}
return cnt;
}
int main(){
fastIO;
cin >> n;
for(int i = 1; i <= n; i ++ ){
cin >> H[i] >> W[i];
H[i] *= 2ll;
W[i] *= 2ll;
if(i > 1){
H[i] -= H[1];
W[i] -= W[1];
}
}
H[1] = 0;
W[1] = 0;
int sol = solve();
for(int i = 1; i <= n; i ++ ){
W[i] = -W[i];
}
sol = max(sol, solve());
for(int i = 1; i <= n; i ++ ){
swap(H[i], W[i]);
}
sol = max(sol, solve());
for(int i = 1; i <= n; i ++ ){
W[i] = -W[i];
}
sol = max(sol, solve());
cout << sol << "\n";
return 0;
}
Compilation message (stderr)
fever.cpp: In function 'int solve()':
fever.cpp:220:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<E>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
220 | if(lf < vv[go[id]][nx].size() && vv[go[id]][nx][lf].val == cur.val){
| ~~~^~~~~~~~~~~~~~~~~~~~~~~
fever.cpp:224:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<E>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
224 | if(nex < vv[go[id]][nx].size() && vv[go[id]][nx][nex].val == cur.val){
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~
# | 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... |