Submission #319806

# Submission time Handle Problem Language Result Execution time Memory
319806 2020-11-06T13:11:24 Z Benq Harbingers (CEOI09_harbingers) C++14
100 / 100
449 ms 31960 KB
#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
using ld = long double;
using db = double; 
using str = string; // yay python!

using pi = pair<int,int>;
using pl = pair<ll,ll>;
using pd = pair<db,db>;

using vi = vector<int>;
using vb = vector<bool>;
using vl = vector<ll>;
using vd = vector<db>; 
using vs = vector<str>;
using vpi = vector<pi>;
using vpl = vector<pl>; 
using vpd = vector<pd>;

#define tcT template<class T
#define tcTU tcT, class U
// ^ lol this makes everything look weird but I'll try it
tcT> using V = vector<T>; 
tcT, size_t SZ> using AR = array<T,SZ>; 
tcT> using PR = pair<T,T>;

// pairs
#define mp make_pair
#define f first
#define s second

// vectors
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend() 
#define sor(x) sort(all(x)) 
#define rsz resize
#define ins insert 
#define ft front() 
#define bk back()
#define pf push_front 
#define pb push_back
#define eb emplace_back 
#define lb lower_bound 
#define ub upper_bound 

// loops
#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 2e5+5;
const ll INF = 1e18; // not too close to LLONG_MAX
const ld PI = acos((ld)-1);
const int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1}; // for every grid problem!!
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count()); 
template<class T> using pqg = priority_queue<T,vector<T>,greater<T>>;

// helper funcs
constexpr int pct(int x) { return __builtin_popcount(x); } // # of bits set
constexpr int bits(int x) { return 31-__builtin_clz(x); } // floor(log2(x)) 
ll cdiv(ll a, ll b) { return a/b+((a^b)>0&&a%b); } // divide a by b rounded up
ll fdiv(ll a, ll b) { return a/b-((a^b)<0&&a%b); } // divide a by b rounded down

tcT> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; } // set a = min(a,b)
tcT> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }

tcTU> T fstTrue(T lo, T hi, U f) {
	hi ++; assert(lo <= hi); // assuming f is increasing
	while (lo < hi) { // find first index such that f is true 
		T mid = lo+(hi-lo)/2;
		f(mid) ? hi = mid : lo = mid+1; 
	} 
	return lo;
}
tcTU> T lstTrue(T lo, T hi, U f) {
	lo --; assert(lo <= hi); // assuming f is decreasing
	while (lo < hi) { // find first index such that f is true 
		T mid = lo+(hi-lo+1)/2;
		f(mid) ? lo = mid : hi = mid-1;
	} 
	return lo;
}
tcT> void remDup(vector<T>& v) { // sort and remove duplicates
	sort(all(v)); v.erase(unique(all(v)),end(v)); }
tcTU> void erase(T& t, const U& u) { // don't erase
	auto it = t.find(u); assert(it != end(t));
	t.erase(u); } // element that doesn't exist from (multi)set

// INPUT
#define tcTUU tcT, class ...U
tcT> void re(complex<T>& c);
tcTU> void re(pair<T,U>& p);
tcT> void re(vector<T>& v);
tcT, size_t SZ> void re(AR<T,SZ>& a);

tcT> void re(T& x) { cin >> x; }
void re(db& d) { str t; re(t); d = stod(t); }
void re(ld& d) { str t; re(t); d = stold(t); }
tcTUU> void re(T& t, U&... u) { re(t); re(u...); }

tcT> void re(complex<T>& c) { T a,b; re(a,b); c = {a,b}; }
tcTU> void re(pair<T,U>& p) { re(p.f,p.s); }
tcT> void re(vector<T>& x) { trav(a,x) re(a); }
tcT, size_t SZ> void re(AR<T,SZ>& x) { trav(a,x) re(a); }
tcT> void rv(int& n, vector<T>& x) { re(n); x.rsz(n); trav(a,x) re(a); }

// TO_STRING
#define ts to_string
str ts(char c) { return str(1,c); }
str ts(const char* s) { return (str)s; }
str ts(str s) { return s; }
str ts(bool b) { 
	#ifdef LOCAL
		return b ? "true" : "false"; 
	#else 
		return ts((int)b);
	#endif
}
tcT> str ts(complex<T> c) { 
	stringstream ss; ss << c; return ss.str(); }
str ts(vector<bool> v) {
	str res = "{"; F0R(i,sz(v)) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> str ts(bitset<SZ> b) {
	str res = ""; F0R(i,SZ) res += char('0'+b[i]);
	return res; }
tcTU> str ts(pair<T,U> p);
tcT> str ts(T v) { // containers with begin(), end()
	#ifdef LOCAL
		bool fst = 1; str res = "{";
		for (const auto& x: v) {
			if (!fst) res += ", ";
			fst = 0; res += ts(x);
		}
		res += "}"; return res;
	#else
		bool fst = 1; str res = "";
		for (const auto& x: v) {
			if (!fst) res += " ";
			fst = 0; res += ts(x);
		}
		return res;

	#endif
}
tcTU> str ts(pair<T,U> p) {
	#ifdef LOCAL
		return "("+ts(p.f)+", "+ts(p.s)+")"; 
	#else
		return ts(p.f)+" "+ts(p.s);
	#endif
}

// OUTPUT
tcT> void pr(T x) { cout << ts(x); }
tcTUU> void pr(const T& t, const U&... u) { 
	pr(t); pr(u...); }
void ps() { pr("\n"); } // print w/ spaces
tcTUU> void ps(const T& t, const U&... u) { 
	pr(t); if (sizeof...(u)) pr(" "); ps(u...); }

// DEBUG
void DBG() { cerr << "]" << endl; }
tcTUU> void DBG(const T& t, const U&... u) {
	cerr << ts(t); if (sizeof...(u)) cerr << ", ";
	DBG(u...); }
#ifdef LOCAL // compile with -DLOCAL, chk -> fake assert
	#define dbg(...) cerr << "Line(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
	#define chk(...) if (!(__VA_ARGS__)) cerr << "Line(" << __LINE__ << ") -> function(" \
		 << __FUNCTION__  << ") -> CHK FAILED: (" << #__VA_ARGS__ << ")" << "\n", exit(0);
#else
	#define dbg(...) 0
	#define chk(...) 0
#endif

// FILE I/O
void setIn(str s) { freopen(s.c_str(),"r",stdin); }
void setOut(str s) { freopen(s.c_str(),"w",stdout); }
void unsyncIO() { cin.tie(0)->sync_with_stdio(0); }
void setIO(str s = "") {
	unsyncIO();
	// cin.exceptions(cin.failbit); 
	// throws exception when do smth illegal
	// ex. try to read letter into int
	if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
}

/**
 * Description: LiChao Segment Tree
 * Source: atatomir, misc
 * Verification: CSA Squared Ends
   * https://judge.yosupo.jp/problem/segment_add_get_min
 */

struct Line {
	int k; ll m;
	Line(int _k, ll _m) { k = _k, m = _m; }
	Line() : Line(0,LLONG_MIN) { }
	ll get(ll x) { return k*x+m; }
	bool majorize(Line X, ll L, ll R) { 
		return get(L) >= X.get(L) && get(R) >= X.get(R); }
};

// struct lc {
// 	lc* c[2]; Line S;
// 	lc() { c[0] = c[1] = NULL; S = Line(); }
// 	~lc() { F0R(i,2) delete c[i]; }
// 	void mc(int i) { if (!c[i]) c[i] = new lc(); }
// 	ll mid(ll x) { return x&1?(x-1)/2:x/2; }
// 	ll query(ll X, ll L, ll R) {
// 		ll ans = S.get(X), M = mid(L+R);
// 		if (X <= M) {
// 			if (c[0]) ckmax(ans,c[0]->query(X,L,M));
// 		} else {
// 			if (c[1]) ckmax(ans,c[1]->query(X,M+1,R));
// 		}
// 		return ans;
// 	}
// 	void modify(Line X, ll L, ll R) {
// 		if (X.majorize(S,L,R)) swap(X,S);
// 		if (S.majorize(X,L,R)) return;
// 		if (S.get(L) < X.get(L)) swap(X,S);
// 		ll M = mid(L+R);
// 		if (X.get(M) >= S.get(M)) swap(X,S), mc(0), c[0]->modify(X,L,M);
// 		else mc(1), c[1]->modify(X,M+1,R);
// 	}
// 	void upd(Line X, ll lo, ll hi, ll L, ll R) {
// 		if (R < lo || hi < L) return;
// 		if (lo <= L && R <= hi) return modify(X,L,R);
// 		ll M = mid(L+R);
// 		if (lo <= M) mc(0), c[0]->upd(X,lo,hi,L,M);
// 		if (hi > M) mc(1), c[1]->upd(X,lo,hi,M+1,R);
// 	}
// };

Line dat[1<<17];
struct LC {
	vi dists;
	vpi st;
	int seg[1<<18];
	ll get(int x, int M) {
		return dat[x].get(dists[M]);
	}
	bool majorize(int x, int y, int L, int R) {
		return get(x,L) <= get(y,L) && get(x,R) <= get(y,R);
	}
	void upd(int x, int ind, int L, int R) {
		if (majorize(x,seg[ind],L,R)) {
			st.pb({ind,seg[ind]});
			swap(x,seg[ind]);
		}
		if (majorize(seg[ind],x,L,R)) return;
		if (get(seg[ind],L) > get(x,L)) {
			st.pb({ind,seg[ind]});
			swap(x,seg[ind]);
		}
		int M = (L+R)/2;
		if (get(x,M) < get(seg[ind],M)) {
			st.pb({ind,seg[ind]});
			swap(x,seg[ind]), upd(x,2*ind,L,M);
		} else upd(x,2*ind+1,M+1,R);
	}
	void upd(int num) {
		upd(num,1,0,sz(dists)-1);
	}
	ll query(int pos, int ind, int L, int R) {
		ll ans = LLONG_MAX;
		ckmin(ans,get(seg[ind],pos));
		if (L != R) {
			int M = (L+R)/2;
			if (pos <= M) ckmin(ans,query(pos,2*ind,L,M));
			else ckmin(ans,query(pos,2*ind+1,M+1,R));
		}
		return ans;
	}
	ll query(int dist) {
		int pos = lb(all(dists),dist)-begin(dists);
		assert(dists[pos] == dist);
		return query(pos,1,0,sz(dists)-1);
	}
	void rollback(int tmp) {
		while (sz(st) > tmp) {
			seg[st.bk.f] = st.bk.s;
			st.pop_back();
		}
	}
};

LC lc;

vpi adj[1<<17];
int dist[1<<17],prep[1<<17],val[1<<17];
ll ans[1<<17];
int N;
vpi mods;

void dfs_ans(int x, int y = -1) {
	if (x > 1) ans[x] = lc.query(val[x])+(ll)val[x]*dist[x]+prep[x];
	int tmp = sz(lc.st);
	dat[x] = {-dist[x],ans[x]};
	lc.upd(x);
	trav(t,adj[x]) if (t.f != y) {
		dfs_ans(t.f,x);
	}
	lc.rollback(tmp);
}

void dfs_dist(int x, int y = -1, int tot = 0) {
	dist[x] = tot;
	trav(t,adj[x]) if (t.f != y) {
		dfs_dist(t.f,x,tot+t.s);
	}
}

int main() {
	setIO(); re(N);
	FOR(i,2,N+1) {
		int u,v,d; re(u,v,d);
		adj[u].pb({v,d}), adj[v].pb({u,d});
	}
	// dfs("AA");
	FOR(i,2,N+1) re(prep[i],val[i]);
	// dfs("BB");
	dfs_dist(1);
	FOR(i,2,N+1) lc.dists.pb(val[i]);
	remDup(lc.dists);
	dat[0] = Line(0,LLONG_MAX);
	dfs_ans(1);
	FOR(i,2,N+1) pr(ans[i],' ');
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
	* DON'T GET STUCK ON ONE APPROACH
*/

Compilation message

harbingers.cpp: In function ‘void setIn(str)’:
harbingers.cpp:185:28: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
  185 | void setIn(str s) { freopen(s.c_str(),"r",stdin); }
      |                     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~
harbingers.cpp: In function ‘void setOut(str)’:
harbingers.cpp:186:29: warning: ignoring return value of ‘FILE* freopen(const char*, const char*, FILE*)’, declared with attribute warn_unused_result [-Wunused-result]
  186 | void setOut(str s) { freopen(s.c_str(),"w",stdout); }
      |                      ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 3 ms 5484 KB Output is correct
2 Correct 6 ms 6252 KB Output is correct
3 Correct 93 ms 18280 KB Output is correct
4 Correct 139 ms 25036 KB Output is correct
5 Correct 171 ms 28000 KB Output is correct
6 Correct 208 ms 31960 KB Output is correct
7 Correct 108 ms 17248 KB Output is correct
8 Correct 449 ms 24656 KB Output is correct
9 Correct 211 ms 29256 KB Output is correct
10 Correct 189 ms 26948 KB Output is correct