Submission #1183942

#TimeUsernameProblemLanguageResultExecution timeMemory
1183942catch_me_if_you_canBulldozer (JOI17_bulldozer)C++20
0 / 100
2 ms968 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+5);
		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;
	}

	int Q()
	{
		return tree[1].S;
	}
};

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];
}

signed main()
{
	fast();
	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];
	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};
	in st = {GG[0][0], GG[0][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<in> srt(n+1);
	for(int i = 1; i <= n; i++)
		srt[i] = {dot(pt[i], st), i};
	sort(srt.begin()+1, srt.end());
	vector<int> s(n+1);
	for(int i = 1; i <= n; i++)
	{
		s[i] = w[srt[i][1]];
		where[srt[i][1]] = i;
	}
	seg_tree work;
	work.init(n, s);
	int ANS = work.Q(); 
	//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;*/
		for(auto [i, j]: T)
		{
			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);
		}
		ANS = max(ANS, work.Q());
	}
	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...