Submission #1144728

#TimeUsernameProblemLanguageResultExecution timeMemory
1144728SmuggingSpunPalembang Bridges (APIO15_bridge)C++20
100 / 100
92 ms5300 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
const ll INF = 1e18;
template<class T>void minimize(T& a, T b){
	if(a > b){
		a = b;
	}
}
int k, n;
namespace sub12{
	void solve(){
		ll ans = 0;
		vector<int>p;
		for(int i = 0; i < n; i++){
			char a, b;
			int xa, xb;
			cin >> a >> xa >> b >> xb;
			if(a == b){
				ans += abs(xa - xb);
			}
			else{
				p.emplace_back(xa);
				p.emplace_back(xb);
				ans++;
			}
		}
		if(!p.empty()){
			sort(p.begin(), p.end());
			int median = p[int(p.size()) >> 1];
			for(int& x : p){
				ans += abs(median - x);
			}
		}
		cout << ans;
	}
}
namespace sub3{
	void solve(){
		vector<int>candidate;
		vector<pair<int, int>>d;
		ll ans = 0;
		for(int i = 0; i < n; i++){
			char a, b;
			int xa, xb;
			cin >> a >> xa >> b >> xb;
			if(a == b){
				ans += abs(xa - xb);
			}
			else{
				candidate.emplace_back(xa);
				candidate.emplace_back(xb);
				ans++;
				d.emplace_back(xa, xb);
			}
		}
		if(!d.empty()){
			ll add = INF;
			sort(candidate.begin(), candidate.end());
			candidate.resize(unique(candidate.begin(), candidate.end()) - candidate.begin());
			for(int i = 0; i < candidate.size(); i++){
				for(int j = i + 1; j < candidate.size(); j++){
					ll sum = 0;
					for(auto& [x, y] : d){
						sum += min(abs(x - candidate[i]) + abs(y - candidate[i]), abs(x - candidate[j]) + abs(y - candidate[j]));				
					}
					minimize(add, sum);
				}
			}
			ans += add;
		}
		cout << ans;
	}
}
namespace sub45{
	const int lim = 2e5 + 5;
	int cnt[lim];
	ll sum[lim];
	void update(int p, int v){
		for(p++; p < lim; p += p & -p){
			cnt[p]++;
			sum[p] += v;
		}
	}
	pair<int, ll>get(int p){
		pair<int, ll>ans = make_pair(0, 0LL);
		for(p++; p > 0; p -= p & -p){
			ans.first += cnt[p];
			ans.second += sum[p];
		}
		return ans;
	}
	void solve(){
		ll ans = 0;
		vector<pair<int, int>>p;
		vector<int>compress;
		for(int i = 0; i < n; i++){
			char a, b;
			int xa, xb;
			cin >> a >> xa >> b >> xb;
			if(a == b){
				ans += abs(xa - xb);
			}
			else{
				p.emplace_back(xa, xb);
				compress.emplace_back(xa);
				compress.emplace_back(xb);
				ans++;
			}
		}
		if(!p.empty()){
			sort(compress.begin(), compress.end());
			compress.resize(unique(compress.begin(), compress.end()) - compress.begin());
			sort(p.begin(), p.end(), [&] (auto i, auto j) -> bool{
				return i.first + i.second < j.first + j.second;
			});
			ll total = 0;
			vector<ll>f(p.size());
			for(int i = 0; i < p.size(); i++){
				auto& [x, y] = p[i];
				x = lower_bound(compress.begin(), compress.end(), x) - compress.begin();
				y = lower_bound(compress.begin(), compress.end(), y) - compress.begin();
				update(x, compress[x]);
				update(y, compress[y]);
				total += compress[x] + compress[y];
				int low = 0, high = int(compress.size()) - 1, median;
				while(low <= high){
					int mid = (low + high) >> 1;
					if(get(mid).first > i){
						high = (median = mid) - 1;
					}
					else{
						low = mid + 1;
					}
				}
				pair<int, ll>down = get(median);
				f[i] = 1LL * down.first * compress[median] - down.second - 1LL * ((i << 1) + 2 - down.first) * compress[median] + total - down.second;
			}
			ll add = f.back();
			memset(cnt, total = 0, sizeof(cnt));
			memset(sum, 0, sizeof(sum));	
			for(int i = int(p.size()) - 1; i > 0; i--){
				auto& [x, y] = p[i];
				update(x, compress[x]);
				update(y, compress[y]);
				total += compress[x] + compress[y];
				int low = 1, high = int(compress.size()) - 1, median;
				while(low <= high){
					int mid = (low + high) >> 1;
					if(get(mid).first >= int(p.size()) - i){
						high = (median = mid) - 1;
					}
					else{
						low = mid + 1;
					}
				}
				pair<int, ll>down = get(median);
				minimize(add, 1LL * down.first * compress[median] - down.second - 1LL * (((int(p.size()) - i) << 1) - down.first) * compress[median] + total - down.second + f[i - 1]);
			}
			ans += add;
		}
		cout << ans;
	}
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
	cin >> k >> n;
	if(k == 1){
		sub12::solve();
	}
	else if(k == 2 && n <= 100){
		sub3::solve();
	}
	else{
		sub45::solve();
	}
}

Compilation message (stderr)

bridge.cpp: In function 'int main()':
bridge.cpp:169:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...