結果

問題 No.2859 Falling Balls
ユーザー shobonvipshobonvip
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #

#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';

}


0