답안 #736625

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
736625 2023-05-06T03:37:38 Z minhcool Palembang Bridges (APIO15_bridge) C++17
8 / 100
2000 ms 22004 KB
#include<bits/stdc++.h>
using namespace std;

#define int long long
#define fi first
#define se second
#define pb push_back
#define mp make_pair

typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef pair<ii, ii> iiii;

const int N = 3e5 + 5;

const int oo = 1e18 + 7, mod = 1e9 + 7;

int n, k, a[N];

vector<pair<int, ii>> queries;

vector<int> diff;

int pref[N], suff[N];

ii IT1[N << 2], IT2[N << 2];

void upd1(int id, int l, int r, int pos, int val){
	if(l == r){
		IT1[id].fi++;
		IT1[id].se -= val;
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) upd1(id << 1, l, mid, pos, val);
	else upd1(id << 1 | 1, mid + 1, r, pos, val);
	IT1[id].fi = IT1[id << 1].fi + IT1[id << 1 | 1].fi;
	IT1[id].se = IT1[id << 1].se + IT1[id << 1 | 1].se;
}

ii total = {0, 0};

void get1(int id, int l, int r, int L, int R){
	if(l > R || r < L) return;
	if(l >= L && r <= R){
		total.fi += IT1[id].fi;
		total.se += IT1[id].se;
		return;
	}
	int mid = (l + r) >> 1;
	get1(id << 1, l, mid, L, R);
	get1(id << 1 | 1, mid + 1, r, L, R);
}

void upd2(int id, int l, int r, int pos, int val){
	if(l == r){
		IT2[id].fi--;
		IT2[id].se += val;
		return;
	}
	int mid = (l + r) >> 1;
	if(pos <= mid) upd2(id << 1, l, mid, pos, val);
	else upd2(id << 1 | 1, mid + 1, r, pos, val);
	IT2[id].fi = IT2[id << 1].fi + IT2[id << 1 | 1].fi;
	IT2[id].se = IT2[id << 1].se + IT2[id << 1 | 1].se;
}

void get2(int id, int l, int r, int L, int R){
	if(l > R || r < L) return;
	if(l >= L && r <= R){
		total.fi += IT2[id].fi;
		total.se += IT2[id].se;
		return;
	}
	int mid = (l + r) >> 1;
	get2(id << 1, l, mid, L, R);
	get2(id << 1 | 1, mid + 1, r, L, R);
}

int cal(int x){
	total = {0, 0};
	int pos = lower_bound(diff.begin(), diff.end(), x) - diff.begin();
	get1(1, 1, diff.size() - 1, 1, pos);
	get2(1, 1, diff.size() - 1, pos, diff.size() - 1);
//	cout << "OK " << x << " " << total.fi << " " << total.se << "\n";
	return x * total.fi + total.se;
}

/*
2 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
*/

void process(){
	cin >> k >> n;
	int answer = 0;
	for(int i = 1; i <= n; i++){
		char a, b;
		int c, d;
		cin >> a >> c >> b >> d;
		if(a == b){
			answer += abs(c - d);
			continue;
		}
		queries.pb({c + d, {min(c, d), max(c, d)}});
		diff.pb(c), diff.pb(d);
	}
	diff.pb(-1);
	sort(queries.begin(), queries.end());
	sort(diff.begin(), diff.end());
	diff.resize(unique(diff.begin(), diff.end()) - diff.begin());
	int cnt = 0;
	for(auto it : queries){
	//	cout << it.fi << " " << it.se.fi << " " << it.se.se << "\n";
		cnt++;
		pref[cnt] = oo;
		int posi1 = lower_bound(diff.begin(), diff.end(), it.se.fi) - diff.begin();
		int posi2 = lower_bound(diff.begin(), diff.end(), it.se.se) - diff.begin();
		upd1(1, 1, diff.size() - 1, posi2, it.se.se);
		upd2(1, 1, diff.size() - 1, posi1, it.se.fi);
		int le = 1, ri = diff.size() - 1;
		while(le < ri - 3){
			int mid1 = (le + le + ri) / 3, mid2 = (le + ri + ri) / 3;
			int x = cal(diff[mid1]), y = cal(diff[mid2]);
			pref[cnt] = min(pref[cnt], min(x, y));
			if(x > y) le = mid1;
			else ri = mid2;
		}
	//	cout << le << " " << ri << "\n";
		for(int i = le; i <= ri; i++) pref[cnt] = min(pref[cnt], cal(diff[i]));
		//cout << cnt << " " << pref[cnt] << "\n";
		//total = {0, 0};
	}
	for(int i = 1; i <= (n << 2); i++){
		IT1[i] = {0, 0}, IT2[i] = {0, 0};
	}
	reverse(queries.begin(), queries.end());
	cnt = queries.size();
	for(auto it : queries){
		cnt--;
		suff[cnt] = oo;
		int posi1 = lower_bound(diff.begin(), diff.end(), it.se.fi) - diff.begin();
		int posi2 = lower_bound(diff.begin(), diff.end(), it.se.se) - diff.begin();
		upd1(1, 1, diff.size() - 1, posi2, it.se.se);
		upd2(1, 1, diff.size() - 1, posi1, it.se.fi);
		int le = 1, ri = diff.size() - 1;
		while(le < ri - 3){
			int mid1 = (le + le + ri) / 3, mid2 = (le + ri + ri) / 3;
			int x = cal(diff[mid1]), y = cal(diff[mid2]);
			suff[cnt] = min(suff[cnt], min(x, y));
			if(x > y) le = mid1;
			else ri = mid2;
		}
		for(int i = le; i <= ri; i++) suff[cnt] = min(suff[cnt], cal(diff[i]));
		//cout << cnt << " " << suff[cnt] << "\n";
	}
	int ans = oo;
	for(int i = 0; i <= queries.size(); i++){
		if(i && i < queries.size() && k == 1) continue;
		ans = min(ans, pref[i] + suff[i]);
	//	cout << i << " " << pref[i] << " " << suff[i] << "\n";
	}
	ans *= 2;
	ans += answer;
	ans += queries.size();
	for(auto it : queries) ans += abs(it.se.fi - it.se.se);
	cout << ans;
	//cout << ans << " " << ans + answer << "\n";
}

signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	process();
}

/*
1 5
B 0 A 4
B 1 B 3
A 5 B 7
B 2 A 6
B 1 A 7
*/

Compilation message

bridge.cpp: In function 'void process()':
bridge.cpp:162:19: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  162 |  for(int i = 0; i <= queries.size(); i++){
      |                 ~~^~~~~~~~~~~~~~~~~
bridge.cpp:163:13: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::pair<long long int, std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  163 |   if(i && i < queries.size() && k == 1) continue;
      |           ~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 11 ms 468 KB Output is correct
5 Correct 12 ms 596 KB Output is correct
6 Correct 1 ms 472 KB Output is correct
7 Correct 10 ms 468 KB Output is correct
8 Correct 10 ms 468 KB Output is correct
9 Correct 11 ms 468 KB Output is correct
10 Correct 1 ms 468 KB Output is correct
11 Correct 11 ms 468 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 12 ms 468 KB Output is correct
5 Correct 10 ms 532 KB Output is correct
6 Correct 1 ms 468 KB Output is correct
7 Correct 11 ms 552 KB Output is correct
8 Correct 10 ms 480 KB Output is correct
9 Correct 10 ms 468 KB Output is correct
10 Correct 2 ms 468 KB Output is correct
11 Correct 11 ms 552 KB Output is correct
12 Correct 44 ms 18420 KB Output is correct
13 Execution timed out 2092 ms 22004 KB Time limit exceeded
14 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 340 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 340 KB Output isn't correct
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 340 KB Output is correct
2 Correct 0 ms 340 KB Output is correct
3 Correct 1 ms 340 KB Output is correct
4 Incorrect 1 ms 340 KB Output isn't correct
5 Halted 0 ms 0 KB -