Submission #391515

#TimeUsernameProblemLanguageResultExecution timeMemory
391515patrikpavic2Road Construction (JOI21_road_construction)C++17
100 / 100
4418 ms102452 KiB
#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
#include <cstring>
#include <unordered_set>

#define X first
#define Y second
#define PB push_back

using namespace std;

typedef long long ll;
typedef pair < int, int > pii;

const int N = 250500;
const int OFF = (1 << 20);

int T[3 * N];
int n, q, po_X[N], po_Y[N];
int ind[3 * N], izb[N];
vector < int > TT[2 * OFF];
ll x[N], y[N];

void update(int lo, int hi, int x){	
	hi += 11, lo += 10;
	for(; hi < 3 * N; hi += hi & -hi)
		T[hi] -= x;
	for(; lo < 3 * N ; lo += lo & -lo)
		T[lo] += x;
}


int query(int x){
	int ret = 0;
	x += 10;
	for(; x ; x -= x & -x)
		ret += T[x];
	return ret;
}

void update2(int i, int a, int b, int lo, int hi, int x){	
	if(lo <= a && b <= hi) {
		TT[i].PB(x);
		return;
	}
	if(a > hi || b < lo) return;
	update2(2 * i, a, (a + b) / 2, lo, hi, x);
	update2(2 * i + 1, (a + b) / 2 + 1, b, lo, hi, x);
}

vector < int > ret;

void query2(int x){
	ret.clear();
	for(x = (x + OFF); x ; x /= 2){
		vector < int > nw;
		for(int y : TT[x])
			if(!izb[y])
				ret.PB(y), nw.PB(y);
		TT[x] = nw;
	}
}


vector < pii > swp;

ll labs(ll x){
	return x > 0 ? x : -x;
}

ll get_dis(int i, int j){
	return max(labs(x[i] - x[j]), labs(y[i] - y[j]));
}

bool cmpX(int A, int B){
	return x[A] < x[B];
}

bool cmpY(int A, int B){
	return y[A] < y[B];
}

ll prebroji(ll k){
	swp.clear();
	memset(T, 0, sizeof(T));
	int A = 0, B = 0, C = 0;
	for(;A < n || B < n || C < n;){
		if(A < n && (B == n || x[po_X[A]] - k <= x[po_X[B]]) && (C == n || x[po_X[A]] - k <= x[po_X[C]] + k))
			swp.PB({0, po_X[A]}), A++;
		else if(B < n && (A == n || x[po_X[B]] < x[po_X[A]] - k) && (C == n || x[po_X[B]] <= x[po_X[C]] + k))
			swp.PB({1, po_X[B]}), B++;
		else
			swp.PB({2, po_X[C]}), C++;
	}
	A = 0, B = 0, C = 0; int siz = 0;
	for(;A < n || B < n || C < n;){
		if(A < n && (B == n || y[po_Y[A]] - k <= y[po_Y[B]]) && (C == n || y[po_Y[A]] - k <= y[po_Y[C]] + k))
			ind[3 * po_Y[A]] = siz++, A++;
		else if(B < n && (A == n || y[po_Y[B]] < y[po_Y[A]] - k) && (C == n || y[po_Y[B]] <= y[po_Y[C]] + k))
			ind[3 * po_Y[B] + 1] = siz++, B++;
		else
			ind[3 * po_Y[C] + 2] = siz++, C++;
	}
	ll ret = 0;
	for(pair < int , int > tmp : swp){
		if(tmp.X == 0)
			update(ind[3 * tmp.Y], ind[3 * tmp.Y + 2], 1);
		else if(tmp.X == 1)
			ret += query(ind[3 * tmp.Y + 1]);
		else
			update(ind[3 * tmp.Y], ind[3 * tmp.Y + 2], -1);
	}
	ret = (ret - n) / 2LL;
	return ret;
}

vector < ll > pot;

void pronadi(ll k){
	swp.clear();
	memset(izb, 0, sizeof(izb));
	int A = 0, B = 0, C = 0;
	for(;A < n || B < n || C < n;){
		if(A < n && (B == n || x[po_X[A]] - k <= x[po_X[B]]) && (C == n || x[po_X[A]] - k <= x[po_X[C]] + k))
			swp.PB({0, po_X[A]}), A++;
		else if(B < n && (A == n || x[po_X[B]] < x[po_X[A]] - k) && (C == n || x[po_X[B]] <= x[po_X[C]] + k))
			swp.PB({1, po_X[B]}), B++;
		else
			swp.PB({2, po_X[C]}), C++;
	}
	A = 0, B = 0, C = 0; int siz = 0;
	for(;A < n || B < n || C < n;){
		if(A < n && (B == n || y[po_Y[A]] - k <= y[po_Y[B]]) && (C == n || y[po_Y[A]] - k <= y[po_Y[C]] + k))
			ind[3 * po_Y[A]] = siz++, A++;
		else if(B < n && (A == n || y[po_Y[B]] < y[po_Y[A]] - k) && (C == n || y[po_Y[B]] <= y[po_Y[C]] + k))
			ind[3 * po_Y[B] + 1] = siz++, B++;
		else
			ind[3 * po_Y[C] + 2] = siz++, C++;
	}
	for(pair < int , int > tmp : swp){
		if(tmp.X == 0)
			update2(1, 0, OFF - 1, ind[3 * tmp.Y], ind[3 * tmp.Y + 2], tmp.Y);
		else if(tmp.X == 1){
			query2(ind[3 * tmp.Y + 1]);
			for(int y : ret)
				if(y < tmp.Y)
					pot.PB(get_dis(y, tmp.Y));
		}
		else
			izb[tmp.Y] = 1;
	}
}


int main(){
	scanf("%d%d", &n, &q);
	for(int i = 0;i < n;i++){
		int tx, ty; scanf("%d%d", &tx, &ty);
		x[i] = tx + ty, y[i] = tx - ty;
		po_X[i] = i, po_Y[i] = i;
	}
	sort(po_X, po_X + n, cmpX);
	sort(po_Y, po_Y + n, cmpY);
	ll mks = 0;
	for(int i = 32;i >= 0;i--)
		if(prebroji(mks + (1LL << i)) < q)
			mks += (1LL << i);
	pronadi(mks); sort(pot.begin(), pot.end());
	for(ll x : pot)
		printf("%lld\n", x);
	
	for(int i = 0;i < q - (int)pot.size();i++)
		printf("%lld\n", mks + 1);
	return 0;
}

Compilation message (stderr)

road_construction.cpp: In function 'int main()':
road_construction.cpp:158:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  158 |  scanf("%d%d", &n, &q);
      |  ~~~~~^~~~~~~~~~~~~~~~
road_construction.cpp:160:20: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  160 |   int tx, ty; scanf("%d%d", &tx, &ty);
      |               ~~~~~^~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...