Submission #787336

# Submission time Handle Problem Language Result Execution time Memory
787336 2023-07-19T05:50:51 Z 박상훈(#10032) 도로 건설 사업 (JOI13_construction) C++17
0 / 100
16 ms 1448 KB
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
constexpr ll INF = 4e18;

struct Event{
	int x, l, r, typ;
	Event(){}
	Event(int _x, int _l, int _r, int _t): x(_x), l(_l), r(_r), typ(_t) {}
	bool operator < (const Event &E)const{
		return tie(x, typ) < tie(E.x, E.typ);
	}
};

struct Seg{
	int tree[400400], sz;
	set<pair<int, int>> st;
	void init(int n){
		sz = n;
		fill(tree, tree+sz*2, 0);
		st.clear();
	}

	void update(int l, int r, int x){
		if (x < 0){
			auto iter = st.lower_bound(pair<int, int>(l, -1));
			while(iter!=st.end() && iter->first <= r) iter = st.erase(iter);
		}

		++r;
		for (l+=sz, r+=sz;l<r;l>>=1, r>>=1){
			if (l&1){
				tree[l] += x;
				l++;
			}
			if (r&1){
				--r;
				tree[r] += x;
			}
		}
	}

	void push(int p, int x){
		auto iter = st.lower_bound(pair<int, int>(p, -1));
		if (iter!=st.end() && iter->first==p) st.erase(iter);

		st.emplace(p, x);
	}

	int query(int p){
		int ret = 0;
		for (p+=sz;p;p>>=1) ret += tree[p];
		if (ret < 0) return ret;

		auto iter = st.lower_bound(pair<int, int>(p, -1));
		if (iter!=st.end() && iter->first==p) return iter->second;
		return 0;
	}
}tree;

struct Edge{
	int u, v, w;
	Edge(){}
	Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) {}

	bool operator < (const Edge &E) const{
		return w < E.w;
	}
};

struct DSU{
	int path[200200];
	void init(int n){
		for (int i=1;i<=n;i++) path[i] = i;
	}

	int find(int s){
		if (s==path[s]) return s;
		return path[s] = find(path[s]);
	}

	bool merge(int s, int v){
		s = find(s), v = find(v);
		if (s==v) return false;
		path[v] = s;
		return true;
	}
}dsu;

int x[200200], y[200200], Px[200200], Py[200200], Qx[200200], Qy[200200];
vector<int> Cx, Cy;
vector<Edge> E;

ll f[200200];
int lim;

inline int dist(int i, int j){return abs(x[i] - x[j]) + abs(y[i] - y[j]);}
void compress(vector<int> &a){
	sort(a.begin(), a.end());
	a.erase(unique(a.begin(), a.end()), a.end());
}
int getidx(const vector<int> &a, int x){return lower_bound(a.begin(), a.end(), x) - a.begin();}

void sweep(int n, int m){
	vector<Event> Q;

	for (int i=1;i<=n;i++){
		Q.emplace_back(x[i], getidx(Cy, y[i]), i, 1);
	}

	for (int i=1;i<=m;i++){
		Q.emplace_back(Px[i], getidx(Cy, Py[i]), getidx(Cy, Qy[i]), 0);
		Q.emplace_back(Qx[i], getidx(Cy, Py[i]), getidx(Cy, Qy[i]), 2);
	}

	tree.init(Cy.size() + 10);
	sort(Q.begin(), Q.end());
	for (auto &[_, l, r, typ]:Q){
		if (typ==0){
			tree.update(l, r, -1);
		}
		else if (typ==1){
			int tmp = tree.query(l);
			if (tmp > 0){
				E.emplace_back(tmp, r, dist(tmp, r));
			} 

			if (tmp >= 0){
				tree.push(l, r);
			}
		}
		else{
			tree.update(l, r, 1);
		}
	}
}

void run(int n){
	dsu.init(n);
	sort(E.begin(), E.end());

	lim = n;
	f[lim] = 0;
	for (auto &[u, v, w]:E){
		if (dsu.merge(u, v)){
			--lim;
			f[lim] = f[lim+1] + w;
		}
	}
}

ll calc(int x, ll c){
	return c*x + f[x];
}

ll query(int c, int mx){
	int l = lim, r = mx;
	ll ans = INF;

	while(r-l>=4){
		int m1 = (l+r)>>1;
		int m2 = m1+1;

		if (calc(m1, c) > calc(m2, c)) l = m1+1;
		else r = m1-1;
	}

	for (int i=l;i<=r;i++) ans = min(ans, calc(i, c));
	return ans==INF?-1:ans;
}

int main(){
	int n, m, q;
	scanf("%d %d %d", &n, &m, &q);

	for (int i=1;i<=n;i++){
		scanf("%d %d", x+i, y+i);
		Cx.push_back(x[i]);
		Cy.push_back(y[i]);
	}

	for (int i=1;i<=m;i++){
		scanf("%d %d %d %d", Px+i, Py+i, Qx+i, Qy+i);
		Cx.push_back(Px[i]);
		Cx.push_back(Qx[i]);

		Cy.push_back(Py[i]);
		Cy.push_back(Qy[i]);
	}

	compress(Cx); compress(Cy);

	sweep(n, m);

	// flip xy
	for (int i=1;i<=n;i++){
		swap(x[i], y[i]);
	}
	for (int i=1;i<=m;i++){
		swap(Px[i], Py[i]);
		swap(Qx[i], Qy[i]);
	}
	swap(Cx, Cy);

	sweep(n, m);

	// get mst
	run(n);

	while(q--){
		int b, h;
		scanf("%d %d", &b, &h);
		printf("%lld\n", query(b, h));
	}
}

Compilation message

construction.cpp: In function 'int main()':
construction.cpp:175:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  175 |  scanf("%d %d %d", &n, &m, &q);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
construction.cpp:178:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  178 |   scanf("%d %d", x+i, y+i);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~
construction.cpp:184:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  184 |   scanf("%d %d %d %d", Px+i, Py+i, Qx+i, Qy+i);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
construction.cpp:213:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  213 |   scanf("%d %d", &b, &h);
      |   ~~~~~^~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 16 ms 1448 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 16 ms 1448 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 16 ms 1448 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 16 ms 1448 KB Output isn't correct
2 Halted 0 ms 0 KB -