답안 #701124

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
701124 2023-02-20T06:50:15 Z minhcool Road Construction (JOI21_road_construction) C++17
0 / 100
10000 ms 379684 KB
#include<bits/stdc++.h>
using namespace std;

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

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;

ii a[N], b[N];

map<ii, int> mp;
// type1[id]: (-x - y), type2[id]: (-x + y)

vector<int> x, y;
vector<int> type1[N << 2], type2[N << 2];
vector<int> bit1[N << 2], bit2[N << 2];

void build(int id, int l, int r){
	bit1[id].resize(r - l + 2), bit2[id].resize(r - l + 2);
	if(l == r){
		type1[id].pb(-b[l].fi - b[l].se);
		type2[id].pb(-b[l].fi + b[l].se);
		return;
	}
	int mid = (l + r) >> 1;
	build(id << 1, l, mid);
	build(id << 1 | 1, mid + 1, r);
	for(auto it : type1[id << 1]) type1[id].pb(it);
	for(auto it : type2[id << 1]) type2[id].pb(it);
	for(auto it : type1[id << 1 | 1]) type1[id].pb(it);
	for(auto it : type2[id << 1 | 1]) type2[id].pb(it);
	sort(type1[id].begin(), type1[id].end());
	sort(type2[id].begin(), type2[id].end());
	type1[id].resize(unique(type1[id].begin(), type1[id].end()) - type1[id].begin());
	type2[id].resize(unique(type2[id].begin(), type2[id].end()) - type2[id].begin());
	bit1[id].resize(type1[id].size() + 1);
	bit2[id].resize(type2[id].size() + 1);
}

void upd1(int id, int id2){
	for(; id2 < bit1[id].size(); id2 += id2 & -id2) bit1[id][id2]++;
}

int get1(int id, int id2){
	int ans = 0;
	for(; id2; id2 -= id2 & -id2){
		ans += bit1[id][id2];
	}
	return ans;
}

void upd2(int id, int id2){
	for(; id2 < bit2[id].size(); id2 += id2 & -id2) bit2[id][id2]++;
}

int get2(int id, int id2){
	int ans = 0;
	for(; id2; id2 -= id2 & -id2){
		ans += bit2[id][id2];
	}
	return ans;
}

void upd(int id, int l, int r, int pos, ii point){
	//cout << id << " " << l << " " << r << "\n";
	int posi = lower_bound(type1[id].begin(), type1[id].end(), -point.fi - point.se) - type1[id].begin();
///	cout << "A " << id << " " << posi << " " << point.fi << " " << point.se << "\n";
	upd1(id, posi);
	posi = lower_bound(type2[id].begin(), type2[id].end(), -point.fi + point.se) - type2[id].begin();
	assert(posi);
//	cout << "B " << id << " " << posi << " " << point.fi << " " << point.se << "\n";
	upd2(id, posi);
	if(l == r) return;
	int mid = (l + r) >> 1;
	if(pos <= mid) upd(id << 1, l, mid, pos, point);
	else upd(id << 1 | 1, mid + 1, r, pos, point);
}

int get(int id, int l, int r, int L, int R, int type, int val){// <= val, return no of pairs
	if(l > R || r < L) return 0;
	if(l >= L && r <= R){
		if(!type){
			int pos = upper_bound(type1[id].begin(), type1[id].end(), val) - type1[id].begin();
			pos--;
			//cout << "OK " << id << " " << pos << " " << type1[id].size() << "\n";
			return get1(id, pos);
		}
		else{
			int pos = upper_bound(type2[id].begin(), type2[id].end(), val) - type2[id].begin();
			pos--;
			//cout << "OK " << id << " " << pos << " " << type2[id].size() << "\n";
			return get2(id, pos);
		}
	}
	int mid = (l + r) >> 1;
	return get(id << 1, l, mid, L, R, type, val) + get(id << 1 | 1, mid + 1, r, L, R, type, val);
}

bool cmp(ii a, ii b){
	return a.se < b.se;
}

priority_queue<int, vector<int>, greater<int>> pq;

int find_mn1(int id, int value){
	int answer = 0;
	for(int i = 19; i >= 0; i--){
		if((answer + (1LL << i)) >= bit1[id].size()) continue;
		if(value > bit1[id][answer + (1LL << i)]){
			value -= bit1[id][answer + (1LL << i)];
			answer += (1LL << i);
		}
	}
	return answer + 1;
}

int find_mn2(int id, int value){
	int answer = 0;
	for(int i = 19; i >= 0; i--){
		if((answer + (1LL << i)) >= bit2[id].size()) continue;
		if(value > bit2[id][answer + (1LL << i)]){
			value -= bit2[id][answer + (1LL << i)];
			answer += (1LL << i);
		}
	}
	return answer + 1;
}

void gett(int id, int l, int r, int L, int R, int type, int val, int plus){
	if(l > R || r < L) return;
	if(l >= L && r <= R){
		if(!type){
			int pos = upper_bound(type1[id].begin(), type1[id].end(), val) - type1[id].begin();
			pos--;
			int tempo = get1(id, pos);
			//cout << tempo << "\n";
			//return;
			for(int i = 1; i <= tempo; i++){
				int posi = find_mn1(id, i);
				//continue;
				assert(posi < type1[id].size());
			//	cout << "OKAY " << type1[id][posi] << " " << plus << "\n";
				pq.push(type1[id][posi] + plus);
			}
			return;
			//return get1(id, pos);
		}
		else{
			int pos = upper_bound(type2[id].begin(), type2[id].end(), val) - type2[id].begin();
			pos--;
			int tempo = get2(id, pos);
			//return;
			for(int i = 1; i <= tempo; i++){
				int posi = find_mn2(id, i);
				assert(posi < type2[id].size());
			//	cout << "OKAY " << type1[id][posi] << " " << plus << "\n";
				pq.push(type2[id][posi] + plus);
			}
			return;
			//return get2(id, pos);
		}
	}
	int mid = (l + r) >> 1;
	gett(id << 1, l, mid, L, R, type, val, plus);
	gett(id << 1 | 1, mid + 1, r, L, R, type, val, plus);
}

void process(){
	cin >> n >> k;
	for(int i = 1; i <= n; i++){
		cin >> a[i].fi >> a[i].se;
		b[i] = a[i];
		x.pb(a[i].fi), y.pb(a[i].se);
	}
	sort(x.begin(), x.end()), sort(y.begin(), y.end());
	x.resize(unique(x.begin(), x.end()) - x.begin());
	y.resize(unique(y.begin(), y.end()) - y.begin());
	sort(a + 1, a + n + 1);
	sort(b + 1, b + n + 1, cmp);
	for(int i = 1; i <= n; i++) mp[b[i]] = i;
	build(1, 1, n);
	for(int i = 1; i <= (n << 2); i++){
		type1[i].pb(-oo), type2[i].pb(-oo);
		sort(type1[i].begin(), type1[i].end());
		sort(type2[i].begin(), type2[i].end());
	}
	int l = 1, r = 2e9 + 5;
	while(l < r){
		int mid = (l + r) >> 1;
		for(int i = 1; i <= (n << 2); i++){
			for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
			for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
		}
		int answer = 0;
		for(int i = 1; i <= n; i++){
			int pos = mp[a[i]];
		//	cout << pos << " ";
			answer += get(1, 1, n, 1, pos, 0, mid - a[i].fi - a[i].se);
			answer += get(1, 1, n, pos + 1, n, 1, mid - a[i].fi + a[i].se);
			//continue;
			//cout << answer << "\n";
			upd(1, 1, n, pos, a[i]);
		}
		//return;
		//cout << mid << " " << answer << "\n";
		if(answer < k) l = mid + 1;
		else r = mid;
	}
	//cout << l << "\n";
	l--;
	for(int i = 1; i <= (n << 2); i++){
		for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
		for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
	}
	for(int i = 1; i <= n; i++){
		int pos = mp[a[i]];
		gett(1, 1, n, 1, pos, 0, l - a[i].fi - a[i].se, a[i].fi + a[i].se);
		gett(1, 1, n, pos + 1, n, 1, l - a[i].fi + a[i].se, a[i].fi - a[i].se);
		//continue;
		upd(1, 1, n, pos, a[i]);
	}
	l++;
	//return;
	assert(pq.size() <= k);
	while(pq.size() < k) pq.push(l);
	for(int i = 1; i <= k; i++){
		int x = pq.top();
		pq.pop();
		cout << x << "\n";
	}
}

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

Compilation message

road_construction.cpp: In function 'void upd1(long long int, long long int)':
road_construction.cpp:51:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   51 |  for(; id2 < bit1[id].size(); id2 += id2 & -id2) bit1[id][id2]++;
      |        ~~~~^~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void upd2(long long int, long long int)':
road_construction.cpp:63:12: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   63 |  for(; id2 < bit2[id].size(); id2 += id2 & -id2) bit2[id][id2]++;
      |        ~~~~^~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'long long int find_mn1(long long int, long long int)':
road_construction.cpp:118:28: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  118 |   if((answer + (1LL << i)) >= bit1[id].size()) continue;
      |      ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'long long int find_mn2(long long int, long long int)':
road_construction.cpp:130:28: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  130 |   if((answer + (1LL << i)) >= bit2[id].size()) continue;
      |      ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from road_construction.cpp:1:
road_construction.cpp: In function 'void gett(long long int, long long int, long long int, long long int, long long int, long long int, long long int, long long int)':
road_construction.cpp:151:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  151 |     assert(posi < type1[id].size());
      |            ~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp:165:17: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  165 |     assert(posi < type2[id].size());
      |            ~~~~~^~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void process()':
road_construction.cpp:201:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  201 |    for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:202:21: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  202 |    for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                   ~~^~~~~~~~~~~~~~~~
road_construction.cpp:222:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  222 |   for(int j = 0; j < bit1[i].size(); j++) bit1[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
road_construction.cpp:223:20: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  223 |   for(int j = 0; j < bit2[i].size(); j++) bit2[i][j] = 0;
      |                  ~~^~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/stdc++.h:33,
                 from road_construction.cpp:1:
road_construction.cpp:234:19: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  234 |  assert(pq.size() <= k);
      |         ~~~~~~~~~~^~~~
road_construction.cpp:235:18: warning: comparison of integer expressions of different signedness: 'std::priority_queue<long long int, std::vector<long long int>, std::greater<long long int> >::size_type' {aka 'long unsigned int'} and 'long long int' [-Wsign-compare]
  235 |  while(pq.size() < k) pq.push(l);
      |        ~~~~~~~~~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 168 ms 118460 KB Output is correct
2 Correct 170 ms 118552 KB Output is correct
3 Incorrect 141 ms 118332 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10028 ms 377440 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10037 ms 379684 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10037 ms 379684 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 168 ms 118460 KB Output is correct
2 Correct 170 ms 118552 KB Output is correct
3 Incorrect 141 ms 118332 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 168 ms 118460 KB Output is correct
2 Correct 170 ms 118552 KB Output is correct
3 Incorrect 141 ms 118332 KB Output isn't correct
4 Halted 0 ms 0 KB -