Submission #1184651

#TimeUsernameProblemLanguageResultExecution timeMemory
1184651catch_me_if_you_canBulldozer (JOI17_bulldozer)C++20
0 / 100
0 ms324 KiB
#include<bits/stdc++.h> using namespace std; #define int long long #define in array<int, 2> #define pb push_back #define pob pop_back #define fast() ios_base::sync_with_stdio(false); cin.tie(NULL) const int MX = 2e3+5; const int INF = 2e18; struct ndata { int L, R, S, T; }; ndata create(int x) { ndata ret; ret.L = ret.R = ret.S = max(x, 0ll); ret.T = x; return ret; } void rev(ndata &d) { swap(d.L, d.R); return; } ndata merge(const ndata &d1, const ndata &d2) { ndata d3; d3.L = max(d1.L, d1.T + d2.L); d3.R = max(d2.R, d2.T + d1.R); d3.S = max(max(d1.S, d2.S), d1.R + d2.L); d3.T = d1.T + d2.T; return d3; } struct seg_tree { vector<ndata> tree; void build(const vector<int> &a, int id, int l, int r) { int m = (l+r)/2; if(l == r) { tree[id] = create(a[m]); return; } build(a, 2*id, l, m); build(a, 2*id+1, m+1, r); tree[id] = merge(tree[2*id], tree[2*id+1]); return; } void init(int n, const vector<int> &a) { tree.resize(4*n+50); build(a, 1, 1, n); return; } void upd(int p, int val, int id, int l, int r) { if(l == r) { tree[id] = create(val); return; } int m = (l+r)/2; if(p <= m) upd(p, val, 2*id, l, m); else upd(p, val, 2*id+1, m+1, r); tree[id] = merge(tree[2*id], tree[2*id+1]); return; } ndata Q(int ql, int qr, int id, int l, int r) { if(qr < l || r < ql) return create(0); if((ql <= l) && (r <= qr)) return tree[id]; int m = (l+r)/2; ndata n1 = Q(ql, qr, 2*id, l, m); ndata n2 = Q(ql, qr, 2*id+1, m+1, r); return merge(n1, n2); } }; in sloppy(in pt1, in pt2) { in zz = {pt1[1]-pt2[1], pt1[0]-pt2[0]}; if(zz[1] < 0) { zz[1] = -zz[1]; zz[0] = -zz[0]; } if(zz[1] == 0) return {1, 0}; int g = __gcd(abs(zz[1]), abs(zz[0])); zz[1]/=g; zz[0]/=g; return zz; } bool comp(array<int, 4> s1, array<int, 4> s2) { int XX = s1[0]*s2[1]; int YY = s2[0]*s1[1]; if(XX < YY) return true; if(XX > YY) return false; return (((in){s1[3], s1[4]}) < ((in){s2[3], s2[4]})); } int dot(in x1, in x2) { return x1[0]*x2[0] - x1[1]*x2[1]; } vector<int> pa(MX, -1); int leader(int u) { if(pa[u] < 0) return u; else return pa[u] = leader(pa[u]); } void murder() { cout << "0\n"; exit(0); return; } vector<in> cmp[MX]; bool active[MX]; vector<int> stuff; vector<in> Tt; vector<in> MOON; vector<int> Spl; void MERGE(int u, int v) { u = leader(u); v = leader(v); if(u == v) return; if(pa[u] < pa[v]) swap(u, v); pa[v]+=pa[u]; pa[u] = v; return; } signed main() { fast(); murder(); int n; cin >> n; vector<in> pt(n+1); vector<int> w(n+1); for(int i = 1; i <= n; i++) cin >> pt[i][0] >> pt[i][1] >> w[i]; if(n == 1) { cout << max(w[1], 0ll) << "\n"; return 0; } vector<array<int, 4>> GG; for(int i = 1; i <= n; i++) { for(int j = i+1; j <= n; j++) { auto [x, y] = sloppy(pt[i], pt[j]); GG.pb({x, y, i, j}); } } sort(GG.begin(), GG.end(), comp); vector<vector<in>> ff; in lst = {-1, -1}; for(auto [x, y, i, j]: GG) { //cout << x << " " << y << endl; if(((in){x, y}) == lst) ff.back().pb({i, j}); else { ff.pb({{i, j}}); lst = {x, y}; } } /*for(auto s: ff) { cout << "Next set: " << endl; for(auto [i, j]: s) cout << pt[i][0] << " " << pt[i][1] << " " << pt[j][0] << " " << pt[j][1] << endl; }*/ vector<int> where(n+1); vector<array<int, 3>> srt(n+1); for(int i = 1; i <= n; i++) srt[i] = {-pt[i][0], -pt[i][1], i}; sort(srt.begin()+1, srt.end()); vector<int> s(n+1); for(int i = 1; i <= n; i++) { s[i] = w[srt[i][2]]; where[srt[i][2]] = i; } //murder(); seg_tree work; work.init(n, s); int ANS = -INF; //cout << st[0] << " " << st[1] << endl; for(auto T: ff) { /*cout << "Current perm " << endl; vector<int> WTF(n+1); for(int i = 1; i <= n; i++) WTF[where[i]] = i; for(int i = 1; i <= n; i++) cout << WTF[i] << " "; cout << endl;*/ stuff.clear(); Tt.clear(); Spl.clear(); MOON.clear(); for(auto [i, j]: T) pa[i] = pa[j] = -1; for(auto [i, j]: T) { if(!active[i]) { stuff.pb(i); active[i] = 1; } if(!active[j]) { stuff.pb(j); active[j] = 1; } MERGE(i, j); } for(auto [i, j]: T) active[i] = active[j] = 0; for(auto x: stuff) { int y = leader(x); cmp[y].pb({where[x], x}); if(cmp[y].size() == 1) Spl.pb(y); } for(auto x: Spl) { sort(cmp[x].begin(), cmp[x].end()); for(int i = 0; (2*i) < (cmp[x].size()-1); i++) Tt.pb({cmp[x][i][1], cmp[x][cmp[x].size()-1-i][1]}); MOON.pb({cmp[x][0][0], cmp[x][cmp[x].size()-1][0]}); cmp[x].clear(); } for(auto [i, j]: Tt) { //cout << "Swapping i, j = " << i << ", " << j << endl; work.upd(where[i], w[j], 1, 1, n); work.upd(where[j], w[i], 1, 1, n); swap(where[i], where[j]); //assert(abs(where[i]-where[j]) == 1); } ndata curr = create(0); int lst = 1; sort(MOON.begin(), MOON.end()); for(auto [l, r]: MOON) { if(l > lst) curr = merge(curr, work.Q(lst, l-1, 1, 1, n)); curr = merge(curr, create(work.Q(l, r, 1, 1, n).T)); lst = r+1; } if(n >= lst) curr = merge(curr, work.Q(lst, n, 1, 1, n)); ANS = max(ANS, curr.S); } cout << ANS << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...