답안 #251994

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
251994 2020-07-23T14:08:28 Z lyc Building Bridges (CEOI17_building) C++14
100 / 100
160 ms 12920 KB
#include <bits/stdc++.h>
using namespace std;

#define TRACE(x) cerr << #x << " :: " << x << endl
#define _ << " " <<
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define RFOR(i,a,b) for (int i=(a);i>=(b);--i)
#define SQ(x) ((ll)(x)*(x))
using ll=long long;
using ld=long double;

const int mxN = 1e5+5;

int N, H[mxN], W[mxN];
ll pW[mxN], dp[mxN];

const ll is_query = -(1LL<<62);

struct Line {
	ll m, c;
	mutable function<const Line*()> succ;
	bool operator < (const Line& rhs) const {
		if (rhs.c != is_query) return m > rhs.m;
		auto s = succ();
		if (!s) return 0;
		ll x = rhs.m;
		return (m - s->m)*x > (s->c - c);
	}
};

struct HullDynamic : multiset<Line> {
	bool bad(iterator y) {
		auto z = next(y);
		if (y == begin()) {
			if (z == end()) return 0;
			return y->m == z->m && y->c >= z->c;
		}
		auto x = prev(y);
		if (z == end()) return y->m == x->m && y->c >= x->c;
		if (y->m == x->m) return y->c >= x->c;
		if (y->m == z->m) return y->c >= z->c;
		return (ld)(y->c - z->c)/(z->m - y->m) <= (y->c - x->c)/(x->m - y->m);
	}
	
	void add(ll m, ll c) {
		auto y = insert({ m,c });
		y->succ = [=]{ return next(y) == end() ? 0 : &*next(y); };
		if (bad(y)) { erase(y); return; }
		while (y != begin() && bad(prev(y))) erase(prev(y));
		while (next(y) != end() && bad(next(y))) erase(next(y));
	}
	
	ll query(int x) {
		auto l = *lower_bound({ x,is_query });
		return l.m*x + l.c;
	}
} ch;

int main() {
	//freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> N;
    FOR(i,1,N){ cin >> H[i]; }
    FOR(i,1,N){ cin >> W[i]; pW[i] = pW[i-1] + W[i]; }
    
    dp[1] = 0;
    ch.add(-2*H[1], SQ(H[1]) - pW[1] + dp[1]);
    FOR(i,2,N){
		// (H[i]-H[j])^2 + pW[i-1]-pW[j] + dp[j];
		dp[i] = ch.query(H[i]) + SQ(H[i]) + pW[i-1];
		ch.add(-2*H[i], SQ(H[i]) - pW[i] + dp[i]);
		//~ TRACE(i);
		//~ for (auto x : ch) cout << x.m << ' ' << x.c << " | ";
		//~ cout << endl;
	}
	cout << dp[N] << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 384 KB Output is correct
2 Correct 0 ms 384 KB Output is correct
3 Correct 0 ms 384 KB Output is correct
4 Correct 1 ms 384 KB Output is correct
5 Correct 1 ms 384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 75 ms 2764 KB Output is correct
2 Correct 80 ms 3832 KB Output is correct
3 Correct 73 ms 3832 KB Output is correct
4 Correct 66 ms 3576 KB Output is correct
5 Correct 93 ms 5500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 384 KB Output is correct
2 Correct 0 ms 384 KB Output is correct
3 Correct 0 ms 384 KB Output is correct
4 Correct 1 ms 384 KB Output is correct
5 Correct 1 ms 384 KB Output is correct
6 Correct 75 ms 2764 KB Output is correct
7 Correct 80 ms 3832 KB Output is correct
8 Correct 73 ms 3832 KB Output is correct
9 Correct 66 ms 3576 KB Output is correct
10 Correct 93 ms 5500 KB Output is correct
11 Correct 66 ms 3960 KB Output is correct
12 Correct 77 ms 3856 KB Output is correct
13 Correct 48 ms 3832 KB Output is correct
14 Correct 71 ms 3960 KB Output is correct
15 Correct 160 ms 12920 KB Output is correct
16 Correct 94 ms 5496 KB Output is correct
17 Correct 28 ms 3708 KB Output is correct
18 Correct 31 ms 3704 KB Output is correct