답안 #33654

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
33654 2017-10-31T07:57:59 Z sinhriv Palembang Bridges (APIO15_bridge) C++14
63 / 100
106 ms 228612 KB
#include <bits/stdc++.h>
 
using namespace std;
 
struct Point{
	int x;
	int y;
 
	void read(){
		char read[5];
		scanf("%s%d", read, &y);
		x = (read[0] - 'A');
	}
};	
 
struct Person{
	Point u;
	Point v;
 
	bool check(){
		u.read();
		v.read();
		return (u.x == v.x);
	}
 
	int calc(int val){
		return abs(u.y - val) + abs(v.y - val);
	}
};
 
vector < pair < int, int > > a;
 
long long One(){
	if(a.size() == 0) return 0;
	int n = a.size();
	vector < int > lst;
 
	for(int i = 0; i < n; ++i){
		lst.push_back(a[i].first);
		lst.push_back(a[i].second);
	}
 
	sort(lst.begin(), lst.end());
 
	long long ans = 0;
 
 
	for(int i = 0; i < n + n; ++i){
		ans += abs(lst[i] - lst[n]);
	}
	return ans + n; 
}
 
const int N = 3e5 + 10;
 
long long prefix[N];
 
 
long long preCalc[N];
 
struct PersistentIT{
	int cnt, root, n;
	int L[N * 10];
	int R[N * 10];
	vector < pair < int, int > > save;
	pair < long long, int > value[N * 10];
 
	#define mid ((l + r) >> 1)
 
	void build(int &x, int l, int r){
		if(x == 0) x = ++cnt;
		if(l == r) {
			value[x] = make_pair(0, 0);
			return;
		}
		build(L[x], l, mid);
		build(R[x], mid + 1, r);
	}	
 
	pair < long long, int > combine(pair < long long, int > u, pair < long long, int > v){
		u.first += v.first;
		u.second += v.second;
		return u;
	}
 
 
	void upd(int &x, int old, int l, int r, int pos, pair < long long, int > val){
		if(l > pos || r < pos){
			x = old;
			return;
		}
		x = ++cnt;
		value[x] = combine(value[old], val);
		if(l == r){
			return;
		}
		upd(L[x], L[old], l, mid, pos, val);
		upd(R[x], R[old], mid + 1, r, pos, val);
		value[x] = combine(value[L[x]], value[R[x]]);
	}
 
 
	pair < long long, int > sub(pair < long long, int > u, pair < long long, int > v){
		u.first -= v.first;
		u.second -= v.second;
		return u;
	}
 
	pair < long long, int > query(int x, int l, int r, int u, int v){
		if(l > v || r < u){
			return make_pair(0, 0);
		}
		if(l >= u && r <= v) {
			return value[x];
		}
		return combine(query(L[x], l, mid, u, v), query(R[x], mid + 1, r, u, v));
	}
 
	void add(int x){
		save.emplace_back(x, root);
	}
 
 
	void Init(int sz){
		n = sz;
		cnt = root = 1;
		build(root, 1, n);
		add(0);
	}
 
	void update(int pos, int val){
		upd(root, root, 1, n, pos, make_pair(val, 1));
	}
 
	pair < long long, int > ask(int x, int l, int r){
		if(x < 0) return make_pair(0, 0);
		return query(x, 1, n, l, r);
	}
 
	pair < long long, int > query2D(int l, int r, int u, int v){
		++l; ++r;
 
		//cout << l << " " << r << " " << u << " " << v << endl;
		if(l > r || u > v) return make_pair(0, 0);
		return sub(ask(save[r].second, u, v), ask(save[l - 1].second, u, v));
	}
}treeInside, treeBig, treeSum;
 
vector < int > lst, arr;
  

#define getIdx(x) (lower_bound(lst.begin(), lst.end(), x) - lst.begin() + 1)
 
long long sumX[N];
long long sumY[N];
 
long long Calc(int x, int y){
	int pos = upper_bound(a.begin(), a.end(), make_pair(x + 1, -1)) - a.begin() - 1;
	long long now = preCalc[lower_bound(arr.begin(), arr.end(), x) - arr.begin()];
	int p = lower_bound(a.begin(), a.end(), make_pair(y, -1)) - a.begin();
	long long tot = prefix[a.size() - 1] - (p > 0 ? prefix[p - 1] : 0) - 2LL * (a.size() - p) * y;
	long long Outside = treeBig.query2D(pos + 1, p - 1, getIdx(y), lst.size()).first;
	auto current = treeInside.query2D(pos + 1, p - 1, 1, getIdx(x + y) - 1);
	long long solve = current.first - 2LL * current.second * x;
	auto smaller = treeSum.query2D(pos + 1, p - 1, getIdx(y), lst.size());
	long long other = sumX[p - 1] - sumX[pos] + sumY[p - 1] - sumY[pos];
	other = 2LL * (p - 1 - pos - current.second - smaller.second) * y - (other - current.first - smaller.first); 
	return now + tot + Outside + solve + other;
 
}

long long work(int l, int r, int x, int y){
	
	int best = max(mid + 1, x);
	long long ret = Calc(arr[mid], arr[best]);

	for(int i = best + 1; i <= y; ++i){
		long long curr = Calc(arr[mid], arr[i]);
		if(curr < ret){
			ret = curr;
			best = i;
		}
	}

	if(l != r){
		ret = min(ret, work(l, mid, x, best));
		ret = min(ret, work(mid + 1, r, best, y));
	}
	return ret;
}
 
long long Three(){
	int n = a.size();
	if(n == 0) return 0;
 
 
	for(int i = 0; i < n; ++i){
		if(a[i].first > a[i].second){
			swap(a[i].first, a[i].second);
		}
		lst.push_back(a[i].first);
		lst.push_back(a[i].second);
 
	}
 
	sort(a.begin(), a.end());
	sort(lst.begin(), lst.end());
	lst.resize(unique(lst.begin(), lst.end()) - lst.begin());
 
	arr = lst;
 
	for(int i = 0; i < n; ++i){
		prefix[i] = a[i].first + a[i].second;
		if(i > 0) prefix[i] += prefix[i - 1];
	}
 
	int small = 0;
 
	long long sum = 0;
	long long total = 0;
	
 
	multiset < int > tree;
 
 
	for(int i = 0; i < lst.size(); ++i){
		int x = lst[i];
		while(small < n && a[small].first <= x){
			sum += a[small].second;
			total += a[small].first;
			tree.insert(a[small].second);
			++small;
		}
		while(!tree.empty() && *tree.begin() <= x){
			sum -= *tree.begin() * 2;
			tree.erase(tree.begin());
		}
 
 
		long long now = (1LL * small * x - total) + (sum + 1LL * (small - 2LL * tree.size()) * x);
		preCalc[i] = now;
	}	
 
	for(int i = 0; i < n; ++i){
		lst.push_back(a[i].first + a[i].second);
	}
 
	sort(lst.begin(), lst.end());
	lst.resize(unique(lst.begin(), lst.end()) - lst.begin());
 
	treeSum.Init(lst.size() + 10);
	treeBig.Init(lst.size() + 10);
	treeInside.Init(lst.size() + 10);
 
 
	for(int i = 0; i < n; ++i){
		treeSum.update(getIdx(a[i].second), a[i].first + a[i].second);
		treeBig.update(getIdx(a[i].second), a[i].second - a[i].first);
 
		//cout << getIdx(a[i].second) << " " << i + 1 << endl;
 
		treeInside.update(getIdx(a[i].first + a[i].second), a[i].first + a[i].second);
 
		treeBig.add(i + 1);
		treeSum.add(i + 1);
		treeInside.add(i + 1);
 
		sumX[i] = a[i].first;
		sumY[i] = a[i].second;
 
		if(i > 0){
			sumX[i] += sumX[i - 1];
			sumY[i] += sumY[i - 1];
		}
	}
 
	long long ans = 1e18;

	if(n >= 5000) return 0;
  
	return work(0, arr.size(), 1, arr.size()) + n;
}	
 
 
int main(){
	if(fopen("1.inp", "r")){
		freopen("1.inp", "r", stdin);
	}
 
	long long out = 0;
 
	int k, n;
	scanf("%d%d", &k, &n);
 
	for(int i = 1; i <= n; ++i){
		Person x;
		if(x.check()){
			out += x.calc(x.u.y);
		}
		else{
			a.emplace_back(x.u.y, x.v.y);
		}
	}
 
 
 
	if(k == 1) cout << One() + out;
	else{
		long long ans = One();
		if(a.size() <= 1000){
			ans = min(ans, Three());
		}
		else{
			ans = min(ans, Three());
		}
 
		cout << ans + out;
	}
	return 0;
}

Compilation message

bridge.cpp: In function 'long long int Three()':
bridge.cpp:226:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 0; i < lst.size(); ++i){
                   ^
bridge.cpp:277:12: warning: unused variable 'ans' [-Wunused-variable]
  long long ans = 1e18;
            ^
bridge.cpp: In function 'int main()':
bridge.cpp:287:31: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   freopen("1.inp", "r", stdin);
                               ^
bridge.cpp:293:23: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d", &k, &n);
                       ^
bridge.cpp: In member function 'void Point::read()':
bridge.cpp:11:26: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%s%d", read, &y);
                          ^
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 222388 KB Output is correct
2 Correct 6 ms 222388 KB Output is correct
3 Correct 3 ms 222388 KB Output is correct
4 Correct 16 ms 222388 KB Output is correct
5 Correct 16 ms 222388 KB Output is correct
6 Correct 6 ms 222388 KB Output is correct
7 Correct 6 ms 222388 KB Output is correct
8 Correct 0 ms 222388 KB Output is correct
9 Correct 13 ms 222388 KB Output is correct
10 Correct 6 ms 222388 KB Output is correct
11 Correct 0 ms 222388 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 222388 KB Output is correct
2 Correct 3 ms 222388 KB Output is correct
3 Correct 9 ms 222388 KB Output is correct
4 Correct 6 ms 222388 KB Output is correct
5 Correct 6 ms 222388 KB Output is correct
6 Correct 13 ms 222388 KB Output is correct
7 Correct 6 ms 222388 KB Output is correct
8 Correct 0 ms 222388 KB Output is correct
9 Correct 6 ms 222388 KB Output is correct
10 Correct 9 ms 222388 KB Output is correct
11 Correct 6 ms 222388 KB Output is correct
12 Correct 46 ms 225544 KB Output is correct
13 Correct 66 ms 225544 KB Output is correct
14 Correct 63 ms 225544 KB Output is correct
15 Correct 46 ms 224008 KB Output is correct
16 Correct 46 ms 225544 KB Output is correct
17 Correct 53 ms 225544 KB Output is correct
18 Correct 73 ms 225544 KB Output is correct
19 Correct 69 ms 225544 KB Output is correct
20 Correct 49 ms 225544 KB Output is correct
21 Correct 63 ms 225544 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 222388 KB Output is correct
2 Correct 3 ms 222388 KB Output is correct
3 Correct 0 ms 222388 KB Output is correct
4 Correct 13 ms 222388 KB Output is correct
5 Correct 9 ms 222388 KB Output is correct
6 Correct 3 ms 222388 KB Output is correct
7 Correct 16 ms 222388 KB Output is correct
8 Correct 9 ms 222388 KB Output is correct
9 Correct 13 ms 222388 KB Output is correct
10 Correct 13 ms 222388 KB Output is correct
11 Correct 9 ms 222388 KB Output is correct
12 Correct 16 ms 222388 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 222388 KB Output is correct
2 Correct 0 ms 222388 KB Output is correct
3 Correct 16 ms 222388 KB Output is correct
4 Correct 16 ms 222388 KB Output is correct
5 Correct 23 ms 222388 KB Output is correct
6 Correct 13 ms 222388 KB Output is correct
7 Correct 13 ms 222388 KB Output is correct
8 Correct 13 ms 222388 KB Output is correct
9 Correct 13 ms 222388 KB Output is correct
10 Correct 13 ms 222388 KB Output is correct
11 Correct 19 ms 222388 KB Output is correct
12 Correct 9 ms 222388 KB Output is correct
13 Correct 13 ms 222388 KB Output is correct
14 Correct 9 ms 222388 KB Output is correct
15 Correct 33 ms 222524 KB Output is correct
16 Correct 3 ms 222388 KB Output is correct
17 Correct 3 ms 222388 KB Output is correct
18 Correct 16 ms 222388 KB Output is correct
19 Correct 3 ms 222520 KB Output is correct
20 Correct 26 ms 222520 KB Output is correct
21 Correct 23 ms 222520 KB Output is correct
22 Correct 36 ms 222524 KB Output is correct
23 Correct 13 ms 222388 KB Output is correct
24 Correct 33 ms 222520 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 222388 KB Output is correct
2 Correct 9 ms 222388 KB Output is correct
3 Correct 3 ms 222388 KB Output is correct
4 Correct 13 ms 222388 KB Output is correct
5 Correct 13 ms 222388 KB Output is correct
6 Correct 19 ms 222388 KB Output is correct
7 Correct 23 ms 222388 KB Output is correct
8 Correct 16 ms 222388 KB Output is correct
9 Correct 6 ms 222388 KB Output is correct
10 Correct 9 ms 222388 KB Output is correct
11 Correct 6 ms 222388 KB Output is correct
12 Correct 13 ms 222388 KB Output is correct
13 Correct 9 ms 222388 KB Output is correct
14 Correct 9 ms 222388 KB Output is correct
15 Correct 33 ms 222524 KB Output is correct
16 Correct 16 ms 222388 KB Output is correct
17 Correct 9 ms 222388 KB Output is correct
18 Correct 9 ms 222388 KB Output is correct
19 Correct 6 ms 222520 KB Output is correct
20 Correct 36 ms 222520 KB Output is correct
21 Correct 33 ms 222520 KB Output is correct
22 Correct 39 ms 222524 KB Output is correct
23 Correct 6 ms 222388 KB Output is correct
24 Correct 33 ms 222520 KB Output is correct
25 Incorrect 106 ms 228612 KB Output isn't correct
26 Halted 0 ms 0 KB -