結果
問題 | No.2859 Falling Balls |
ユーザー | shobonvip |
提出日時 | 2024-09-20 20:06:07 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 1,212 ms / 3,000 ms |
コード長 | 5,807 bytes |
コンパイル時間 | 5,028 ms |
コンパイル使用メモリ | 290,184 KB |
実行使用メモリ | 202,416 KB |
最終ジャッジ日時 | 2024-09-20 20:06:37 |
合計ジャッジ時間 | 25,415 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 1 ms
5,376 KB |
testcase_02 | AC | 1 ms
5,376 KB |
testcase_03 | AC | 1 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 1 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 287 ms
53,744 KB |
testcase_11 | AC | 1,070 ms
187,572 KB |
testcase_12 | AC | 43 ms
12,544 KB |
testcase_13 | AC | 1,007 ms
178,888 KB |
testcase_14 | AC | 867 ms
161,328 KB |
testcase_15 | AC | 289 ms
52,516 KB |
testcase_16 | AC | 389 ms
80,228 KB |
testcase_17 | AC | 395 ms
78,852 KB |
testcase_18 | AC | 30 ms
8,960 KB |
testcase_19 | AC | 548 ms
103,348 KB |
testcase_20 | AC | 1,127 ms
202,304 KB |
testcase_21 | AC | 1,212 ms
202,412 KB |
testcase_22 | AC | 1,164 ms
202,300 KB |
testcase_23 | AC | 1,135 ms
202,416 KB |
testcase_24 | AC | 1,126 ms
202,416 KB |
testcase_25 | AC | 1,141 ms
202,284 KB |
testcase_26 | AC | 1,163 ms
202,284 KB |
testcase_27 | AC | 1,100 ms
202,284 KB |
testcase_28 | AC | 1,125 ms
202,168 KB |
testcase_29 | AC | 1,174 ms
202,296 KB |
ソースコード
#include<bits/stdc++.h> using namespace std; //* ATCODER #include<atcoder/all> using namespace atcoder; typedef modint998244353 mint; //*/ /* BOOST MULTIPRECISION #include<boost/multiprecision/cpp_int.hpp> using namespace boost::multiprecision; //*/ typedef long long ll; #define rep(i, s, n) for (int i = (int)(s); i < (int)(n); i++) #define rrep(i, s, n) for (int i = (int)(n)-1; i >= (int)(s); i--) template <typename T> bool chmin(T &a, const T &b) { if (a <= b) return false; a = b; return true; } template <typename T> bool chmax(T &a, const T &b) { if (a >= b) return false; a = b; return true; } template <typename T> T max(vector<T> &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmax(ret, a[i]); return ret; } template <typename T> T min(vector<T> &a){ assert(!a.empty()); T ret = a[0]; for (int i=0; i<(int)a.size(); i++) chmin(ret, a[i]); return ret; } template <typename T> T sum(vector<T> &a){ T ret = 0; for (int i=0; i<(int)a.size(); i++) ret += a[i]; return ret; } #include<atcoder/segtree> template <typename S, S (*op)(S, S), S (*e)(), typename IntType> struct range_tree { typedef std::pair<IntType, IntType> Point; public: range_tree() {} void add_point(IntType a, IntType b) { points.emplace_back(Point{a, b}); } std::vector<Point> merge_points(std::vector<Point> &a, std::vector<Point> &b) { std::vector<Point> ret((int)a.size() + (int)b.size()); int piv = 0; int piva = 0; int pivb = 0; while (piva < (int)a.size() || pivb < (int)b.size()) { if (piva == (int)a.size()) { ret[piv++] = b[pivb++]; }else if(pivb == (int)b.size()){ ret[piv++] = a[piva++]; }else{ if (a[piva].second <= b[pivb].second) { assert(a[piva].first < b[pivb].first); ret[piv++] = a[piva++]; }else{ ret[piv++] = b[pivb++]; } } } assert(piv == (int)a.size() + (int)b.size()); return ret; } void build() { std::sort(points.begin(), points.end()); points.erase(unique(points.begin(), points.end()), points.end()); if (points.empty()) return; IntType memo = points[0].first; xlist.emplace_back(memo); std::vector<std::vector<Point>> tmp_idy(1, std::vector<Point>(1,points[0])); for (int i=1; i<(int)points.size(); i++){ if (points[i].first != memo) { assert(memo < points[i].first); tmp_idy.emplace_back(std::vector<Point>(1, points[i])); memo = points[i].first; xlist.emplace_back(memo); }else{ tmp_idy.back().emplace_back(points[i]); } } assert(tmp_idy.size() == xlist.size()); n = (int)xlist.size(); sz = 1; while (sz < n) { sz <<= 1; } idy.resize(2 * sz); seg.resize(2 * sz); for (int i=0; i<(int)xlist.size(); i++){ idy[i+sz] = tmp_idy[i]; seg[i+sz] = atcoder::segtree<S,op,e>((int)idy[i+sz].size()); } for (int i=sz-1; i>=1; i--){ idy[i] = merge_points(idy[2*i], idy[2*i+1]); seg[i] = atcoder::segtree<S,op,e>((int)idy[i].size()); } } int y_lower_bound(std::vector<Point> &a, IntType q) { int ub = (int)a.size() + 1; int lb = 0; while (ub - lb > 1) { int t = (ub + lb) / 2; if (q > a[t-1].second) { lb = t; }else{ ub = t; } } return lb; } int yx_lower_bound(std::vector<Point> &a, Point &p) { int ub = (int)a.size() + 1; int lb = 0; while (ub - lb > 1) { int t = (ub + lb) / 2; if (p.second > a[t-1].second || (p.second == a[t-1].second && p.first > a[t-1].first)) { lb = t; }else{ ub = t; } } return lb; } S get(IntType x, IntType y) { Point p = Point{x, y}; int i = lower_bound(points.begin(), points.end(), p) - points.begin(); if (i == (int)points.size()) return e(); if (points[i] != p) return e(); return seg[1].get(yx_lower_bound(idy[1], p)); } S prod_inner(int ind, IntType d, IntType u) { int di = y_lower_bound(idy[ind], d); int ui = y_lower_bound(idy[ind], u); return seg[ind].prod(di, ui); } S prod(IntType l, IntType r, IntType d, IntType u) { int li = lower_bound(xlist.begin(), xlist.end(), l) - xlist.begin(); int ri = lower_bound(xlist.begin(), xlist.end(), r) - xlist.begin(); li += sz; ri += sz; S retl = e(), retr = e(); while (li < ri) { if (li & 1) { retl = op(retl, prod_inner(li, d, u)); li++; } if (ri & 1){ ri--; retr = op(prod_inner(ri, d, u), retr); } li >>= 1; ri >>= 1; } return op(retl, retr); } void set(IntType x, IntType y, S val) { Point p = Point{x, y}; int i = lower_bound(points.begin(), points.end(), p) - points.begin(); assert (i < (int)points.size()); assert (points[i] == p); int xi = lower_bound(xlist.begin(), xlist.end(), p.first) - xlist.begin(); xi += sz; while (xi > 0) { seg[xi].set(yx_lower_bound(idy[xi], p), val); xi >>= 1; } } private: int n, sz; std::vector<Point> points; std::vector<IntType> xlist; std::vector<std::vector<Point>> idy; std::vector<atcoder::segtree<S,op,e>> seg; }; ll op(ll a, ll b){ return max(a, b); } ll e(){ return -1e18; } int main(){ int n; cin >> n; ll k; cin >> k; vector<ll> t(n), x(n), c(n); vector<tuple<ll,ll,ll>> f(n); rep(i,0,n) cin >> t[i]; rep(i,0,n) cin >> x[i]; rep(i,0,n) cin >> c[i]; rep(i,0,n) f[i] = make_tuple(t[i], x[i], c[i]); sort(f.begin(), f.end()); rep(i,0,n){ t[i] = get<0>(f[i]); x[i] = get<1>(f[i]); c[i] = get<2>(f[i]); } range_tree<ll,op,e,ll> wm; rep(i,0,n){ wm.add_point(x[i]+k*t[i], x[i]-k*t[i]); } wm.add_point(0, 0); wm.build(); wm.set(0, 0, 0); rep(i,0,n){ ll X = x[i]+k*t[i]; ll Y = x[i]-k*t[i]; ll Z = wm.prod(-9e18, X+1, Y, 9e18) + c[i]; wm.set(X, Y, Z); } cout << wm.prod(-9e18, 9e18, -9e18, 9e18) << '\n'; }