QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#829294 | #9776. Best Friend, Worst Enemy | ucup-team5243 | WA | 205ms | 23476kb | C++17 | 10.0kb | 2024-12-24 08:59:10 | 2024-12-24 08:59:11 |
Judging History
answer
#ifdef NACHIA
#define _GLIBCXX_DEBUG
#else
#define NDEBUG
#endif
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using i64 = long long;
using u64 = unsigned long long;
#define rep(i,n) for(int i=0; i<int(n); i++)
const i64 INF = 1001001001001001001;
template<typename A> void chmin(A& l, const A& r){ if(r < l) l = r; }
template<typename A> void chmax(A& l, const A& r){ if(l < r) l = r; }
using namespace std;
#include <tuple>
namespace nachia{
template<
class S,
S op(S l, S r)
>
struct Segtree {
private:
int N;
std::vector<S> A;
int xN;
void mergev(int i){
if(i < N) A[i] = op(A[i*2], A[i*2+1]);
}
template<class E>
int minLeft2(int r, E cmp, int a = 0, int b = 0, int i = -1) const {
static S x;
if(i == -1){ a=0; b=N; i=1; x=A[0]; }
if(r <= a) return a;
if(b <= r){
S nx = op(A[i], x);
if(cmp(nx)){ x = nx; return a; }
}
if(b - a == 1) return b;
int q = minLeft2(r, cmp, (a+b)/2, b, i*2+1);
if(q > (a+b)/2) return q;
return minLeft2(r, cmp, a, (a+b)/2, i*2);
}
template<class E>
int maxRight2(int l, E cmp, int a = 0, int b = 0, int i = -1) const {
static S x;
if(i == -1){ a=0; b=N; i=1; x=A[0]; }
if(b <= l) return b;
if(l <= a){
S nx = op(x, A[i]);
if(cmp(nx)){ x = nx; return b; }
}
if(b - a == 1) return a;
int q = maxRight2(l, cmp, a, (a+b)/2, i*2);
if(q < (a+b)/2) return q;
return maxRight2(l, cmp, (a+b)/2, b, i*2+1);
}
public:
Segtree() : N(0) {}
Segtree(int n, S e) : xN(n) {
N = 1; while (N < n) N *= 2;
A.assign(N * 2, e);
}
Segtree(const std::vector<S>& a, S e) : Segtree(a.size(), e){
for(int i=0; i<(int)a.size(); i++) A[i + N] = a[i];
for(int i=N-1; i>=1; i--) mergev(i);
}
S getE() const { return A[0]; }
void set(int p, S x){
p += N; A[p] = x;
for(int d=1; (1<<d)<=N; d++) mergev(p>>d);
}
S get(int p) const { return A[N+p]; }
S prod(int l, int r) const {
l += N; r += N;
S ql = A[0], qr = A[0];
while(l<r){
if(l&1) ql = op(ql, A[l++]);
if(r&1) qr = op(A[--r], qr);
l /= 2;
r /= 2;
}
return op(ql, qr);
}
S allProd() const { return A[1]; }
// bool cmp(S)
template<class E>
int minLeft(int r, E cmp) const {
return minLeft2(r, cmp);
}
// bool cmp(S)
template<class E>
int maxRight(int l, E cmp) const {
int x = maxRight2(l, cmp);
return x > xN ? xN : x;
}
};
} // namespace nachia
namespace nachia {
template<class T>
struct PointAddRangeSum{
private:
static T addop(T l, T r){ return l + r; }
using Base = Segtree<T, addop>;
Base base;
public:
PointAddRangeSum() {}
PointAddRangeSum(int len, T Zero)
: base(len, Zero){}
PointAddRangeSum(const std::vector<T>& init, T Zero)
: base(init, Zero){}
T sum(int l, int r){ return base.prod(l, r); }
T sum(){ return base.allProd(); }
void set(int pos, T val){ base.set(pos, val); }
void add(int pos, T val){ base.set(pos, base.get(pos) + val); }
T get(int pos){ return base.get(pos); }
int lBoundLeft(int from, T val){ return base.minLeft(from, [this,val](const T& x){ return x < val; }); }
int uBoundLeft(int from, T val){ return base.minLeft(from, [this,val](const T& x){ return !(val < x); }); }
int lBoundRight(int from, T val){ return base.maxRight(from, [this,val](const T& x){ return x < val; }); }
int uBoundRight(int from, T val){ return base.maxRight(from, [this,val](const T& x){ return !(val < x); }); }
template<class E>
int minLeft(int r, E cmp){ return base.minLeft(r, cmp); }
template<class E>
int maxRight(int l, E cmp){ return base.maxRight(l, cmp); }
};
} // namespace nachia
string ToString(const vector<int>& l){
string res = "[ ";
for(auto i : l){
res += to_string(i);
res += " ";
}
res += "]";
return res;
}
void testcase(){
i64 N; cin >> N;
vector<pair<int,int>> XY(N);
rep(i,N){ int x,y; cin >> x >> y; XY[i] = { x,y }; }
vector<int> IX(N);
rep(i,N) IX[i] = i;
sort(IX.begin(), IX.end(),
[&](int l, int r){ return XY[l] < XY[r]; });
vector<int> IY(N);
rep(i,N) IY[i] = i;
sort(IY.begin(), IY.end(),
[&](int l, int r){
auto [xl,yl] = XY[l];
auto [xr,yr] = XY[r];
return make_pair(yl,xl) < make_pair(yr,xr);
});
vector<int> OX(N), OY(N);
rep(i,N) OX[IX[i]] = i;
rep(i,N) OY[IY[i]] = i;
//cout << "IX : " << ToString(IX) << "\n";
//cout << "OX : " << ToString(OX) << "\n";
//cout << "IY : " << ToString(IY) << "\n";
//cout << "OY : " << ToString(OY) << "\n";
//cout << endl;
nachia::PointAddRangeSum<int> TX(N,0), TY(N,0);
int dxs[4] = { -1, -1, 1, 1 };
int dys[4] = { -1, 1, 1, -1 };
int maxpol[4]; rep(d,4) maxpol[d] = -1000000000;
auto maxManhattan = [&](int p) -> int {
auto [x,y] = XY[p];
int res = 0;
rep(d,4) chmax(res, maxpol[d] - x * dxs[d] - y * dys[d]);
return res;
};
vector<pair<int,int>> XYS(N);
rep(i,N) XYS[i] = XY[IX[i]];
auto exist = [&](int x, int y) -> int {
int i = lower_bound(XYS.begin(), XYS.end(), make_pair(x,y)) - XYS.begin();
//cout << "i = " << i << " " << x << "," << y << endl;
if(i < N && XYS[i] == make_pair(x,y)) return IX[i];
return -1;
};
auto lbix = [&](vector<int>& a, int x) -> int {
//cout << "a = " << ToString(a) << endl;
//cout << "x = " << x << endl;
return lower_bound(a.begin(), a.end(), x,
[&](int l, int x){ return XY[l].first < x; }) - a.begin();
};
auto lbiy = [&](vector<int>& a, int x) -> int {
//cout << "a = " << ToString(a) << endl;
//cout << "x = " << x << endl;
return lower_bound(a.begin(), a.end(), x,
[&](int l, int x){ return XY[l].second < x; }) - a.begin();
};
auto dist1 = [&](int p, int q){
auto [xp,yp] = XY[p];
auto [xq,yq] = XY[q];
return abs(xp-xq) + abs(yp-yq);
};
auto dist2 = [&](int p, int q){
auto [xp,yp] = XY[p];
auto [xq,yq] = XY[q];
return max(abs(xp-xq), abs(yp-yq));
};
int K = 0;
auto border = [&](int p) -> pair<int,int> {
auto [x,y] = XY[p];
int maxm = maxManhattan(p);
int cntout = 0;
int xli = lbix(IX, x - (maxm)/2);
int xri = lbix(IX, x + (maxm)/2 + 1);
int yli = lbiy(IY, y - (maxm)/2);
int yri = lbiy(IY, y + (maxm)/2 + 1);
cntout += K - TX.sum(xli, xri);
cntout += K - TY.sum(yli, yri);
//cout << "cntout = " << cntout << endl;
int mincd = maxm;
if(maxm % 2 == 0) rep(d,4){
int ex = exist(x + maxm/2 * dxs[d], y + maxm/2 * dys[d]) >= 0 ? 1 : 0;
if(ex){ cntout++; chmin(mincd, maxm/2); }
}
if(cntout < K) return {-1,-1};
//cout << "mincd = " << mincd << endl;
int xlbound = TX.uBoundLeft(xli, 0);
if(xlbound != 0) chmin(mincd, x - XY[IX[xlbound-1]].first);
int xrbound = TX.uBoundRight(xri, 0);
if(xrbound != N) chmin(mincd, XY[IX[xrbound]].first - x);
int ylbound = TY.uBoundLeft(yli, 0);
if(ylbound != 0) chmin(mincd, y - XY[IY[ylbound-1]].second);
int yrbound = TY.uBoundRight(yri, 0);
if(yrbound != N) chmin(mincd, XY[IY[yrbound]].second - y);
//cout << "mincd = " << mincd << endl;
return { maxm, mincd };
};
struct Valid{
int p;
int maxdist1;
int mindist2;
vector<int> li;
};
vector<Valid> valids;
for(int i=0; i<N; i++){
auto [x,y] = XY[IX[i]];
if(i >= 2){
rep(vi,valids.size()){
auto& v = valids[vi];
int d1 = dist1(v.p, i);
int d2 = dist2(v.p, i);
if(v.maxdist1 < d1){ v.maxdist1 = d1; v.li.clear(); }
if(v.mindist2 > d2){ v.mindist2 = d2; v.li.clear(); }
if(v.maxdist1 > 2 * v.mindist2){
swap(valids.back(), v); valids.pop_back(); vi--;
continue;
}
if(v.maxdist1 == d1 && v.mindist2 == d2) v.li.push_back(i);
}
auto [u,v] = border(i);
if(u != -1){
Valid q;
q.p = i; q.maxdist1 = u; q.mindist2 = v;
rep(d,4){
int p1 = exist(x + v*dxs[d], y + (u-v)*dys[d]);
if(p1 >= 0 && p1 < i) q.li.push_back(p1);
int p2 = exist(x + (u-v)*dxs[d], y + v*dys[d]);
if(p2 >= 0 && p2 < i) q.li.push_back(p2);
}
sort(q.li.begin(), q.li.end());
q.li.erase(unique(q.li.begin(), q.li.end()), q.li.end());
valids.push_back(move(q));
}
//cout << "valids : \n";
//for(auto& v : valids) cout << " (" << v.p << " " << v.maxdist1 << " " << v.mindist2 << " " << ToString(v.li) << ")\n";
//cout << endl;
int ans = 0;
for(auto& v : valids) ans += int(v.li.size());
cout << ans << "\n";
} else if(i == 1){
valids.push_back({ 0, dist1(0,1), dist2(0,1), {1} });
valids.push_back({ 1, dist1(0,1), dist2(0,1), {0} });
cout << "2\n";
} else{ cout << "0\n"; }
TX.add(OX[i], 1);
TY.add(OY[i], 1);
rep(d,4) chmax(maxpol[d], x * dxs[d] + y * dys[d]);
K++;
}
}
int main(){
ios::sync_with_stdio(false); cin.tie(nullptr);
testcase();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3568kb
input:
2 1 5 1 10
output:
0 2
result:
ok 2 number(s): "0 2"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3852kb
input:
4 2 5 5 3 5 7 8 5
output:
0 2 4 4
result:
ok 4 number(s): "0 2 4 4"
Test #3:
score: 0
Accepted
time: 0ms
memory: 3824kb
input:
9 3 4 3 6 4 3 4 7 5 5 6 3 6 7 7 4 7 6
output:
0 2 1 0 4 5 6 7 8
result:
ok 9 numbers
Test #4:
score: 0
Accepted
time: 0ms
memory: 3628kb
input:
13 3 5 4 4 4 5 4 6 5 3 5 4 5 5 5 6 5 7 6 4 6 5 6 6 7 5
output:
0 2 4 7 2 2 5 2 2 3 3 4 4
result:
ok 13 numbers
Test #5:
score: -100
Wrong Answer
time: 205ms
memory: 23476kb
input:
384010 200000 1000000 200000 1000001 199999 1000000 200001 1000000 200000 999999 200000 1000002 200002 1000000 200000 999998 199998 1000000 199997 1000000 200003 1000000 200000 999997 200000 1000003 199996 1000000 200004 1000000 200000 1000004 200000 999996 199995 1000000 200000 1000005 200000 99999...
output:
0 2 3 5 6 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
result:
wrong answer 3rd numbers differ - expected: '4', found: '3'