답안 #1107502

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1107502 2024-11-01T10:54:47 Z thieunguyenhuy 통행료 (IOI18_highway) C++17
51 / 100
169 ms 31840 KB
#ifndef hwe
	#include "highway.h"
#endif
 
#include <bits/stdc++.h>
using namespace std;
 
#define popcount(n) (__builtin_popcountll((n)))
#define clz(n) (__builtin_clzll((n)))
#define ctz(n) (__builtin_ctzll((n)))
#define lg(n) (63 - __builtin_clzll((n)))
#define BIT(n, i) (((n) >> (i)) & 1ll)
#define MASK(i) (1ll << (i))
#define FLIP(n, i) ((n) ^ (1ll << (i)))
#define ON(n, i) ((n) | MASK(i))
#define OFF(n, i) ((n) & ~MASK(i))
 
#define Int __int128
#define fi first
#define se second
 
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef pair<long long, int> pli;
typedef pair<int, long long> pil;
typedef vector<pair<int, int>> vii;
typedef vector<pair<long long, long long>> vll;
typedef vector<pair<long long, int>> vli;
typedef vector<pair<int, long long>> vil;
 
template <class T1, class T2>
bool maximize(T1 &x, T2 y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <class T1, class T2>
bool minimize(T1 &x, T2 y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}
 
template <class T>
void remove_duplicate(vector<T> &ve) {
    sort (ve.begin(), ve.end());
    ve.resize(unique(ve.begin(), ve.end()) - ve.begin());
}
 
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
template <class T> T random(T l, T r) {
    return uniform_int_distribution<T>(l, r)(rng);
}
template <class T> T random(T r) {
    return rng() % r;
}
 
const int N = 90000 + 5;
const int MOD = 1e9 + 7;
const int inf = 1e9;
const ll INF = 1e18;
 
const int LIGHT = 0, HEAVY = 1;
 
int asked = 0, dist[2][N], edge[N], ver[N], dep[N];
vii adj[N];
vector<int> ve[N];
map<vector<int>, ll> mem;

#ifdef hwe
namespace Grader {
	int n, m, s, t;
	ll dist[N];
	int trace[N];
	pii edges[N];
	vii adj[N];
	vector<int> w;
 
	void get() {
		cin >> n >> m >> s >> t;
	
		for (int i = 0; i < n; ++i) adj[i].clear();

		for (int i = 0; i < m; ++i) {
			int u, v; cin >> u >> v;
			adj[u].emplace_back(v, i), adj[v].emplace_back(u, i);
			edges[i] = make_pair(u, v);
		}
	}
 
	void rand() {
		n = random(7, 7), m = random(n - 1, 15), s = random(n), t = random(n);
		while (s == t) t = random(n);
		for (int i = 1; i < n; ++i) {
			edges[i - 1] = make_pair(random(i), i);
		}
		for (int i = n - 1; i < m; ++i) {
			edges[i] = make_pair(random(n), random(n));
		}
		for (int i = 0; i < n; ++i) adj[i].clear();
		for (int i = 0; i < m; ++i) {
			int u, v; tie(u, v) = edges[i];
			adj[u].emplace_back(v, i), adj[v].emplace_back(u, i);
		}
	}
 
	void show() {
		cerr << n << ' ' << m << ' ' << s << ' ' << t << '\n';
		for (int i = 0; i < m; ++i) cerr << edges[i].fi << ' ' << edges[i].se << '\n';
	}
 
	ll dijkstra(int s, int t) {
		memset(dist, 0x0f, sizeof dist); dist[s] = 0;
		priority_queue<pli, vli, greater<pli>> pq; pq.emplace(0, s);
		while (!pq.empty()) {
			int u = pq.top().se; pq.pop();
			// cerr << "dijkstra " << u << ' ' << dist[u] << '\n';
			for (auto [v, id] : adj[u]) if (minimize(dist[v], dist[u] + w[id])) {
				trace[v] = id;
				pq.emplace(dist[v], v);
			}
		}
		int ma = -1; for (auto &x : w) maximize(ma, x);
		if (ma <= 1) cerr << "kq " << dist[t] << '\n';
		return dist[t];
	}

	void Trace() {
		cerr << "trace "; int v = t;
		while (true) {
			cerr << trace[v] << ' ';
			v = edges[trace[v]].fi ^ edges[trace[v]].se ^ v;
			if (v == s) break;
		}
	}
 
	ll ask(const vector<int> &_w) {
		w = _w; for (auto &x : w) ++x;
		return dijkstra(s, t);
	}
}
 
ll ask(const vector<int> &w) {
	return Grader::ask(w);
}
 
void answer(int s, int t) {
	cerr << "Answer " << s << ' ' << t << '\n';
	pii ans = make_pair(Grader::s, Grader::t);
	if (make_pair(s, t) != ans && make_pair(t, s) != ans) {
		cerr << "Wrong Answer\n";
		exit(0);
	}
}
#endif
 
ll myask(const vector<int> &w) {
	auto it = mem.find(w);
	if (it != mem.end()) return it->se;
	assert(++asked <= 50);
	return mem[w] = ask(w);
}
 
void bfs(const int type, int root) {
	memset(dist[type], -1, sizeof dist[type]); dist[type][root] = 0;
	queue<int> q; q.emplace(root);
	while (!q.empty()) {
		int u = q.front(); q.pop();
		for (auto [v, id] : adj[u]) if (dist[type][v] == -1) {
			dist[type][v] = dist[type][u] + 1;
			q.emplace(v);
		}
	}
}

void print(vector<int> &ve) {
	for (auto &x : ve) cerr << x << ' ';
	cerr << '\n';
}
 
void find_pair(int n, vector<int> U, vector<int> V, int A, int B) {
	int m = U.size(); asked = 0;
	for (int i = 0; i < n; ++i) adj[i].clear();
	for (int i = 0; i < m; ++i) {
		adj[U[i]].emplace_back(V[i], i), adj[V[i]].emplace_back(U[i], i);
	}
 
	vector<int> w(m, LIGHT); mem.clear();
	ll fixed = myask(w);

	int low = 0, high = m - 1, edgeId = -1;
	while (low <= high) {
		int mid = low + high >> 1; vector<int> w(m, LIGHT);
		for (int i = 0; i <= mid; ++i) w[i] = HEAVY;
		if (myask(w) != fixed) high = (edgeId = mid) - 1;
		else low = mid + 1;
	}
	int u = U[edgeId], v = V[edgeId];

	// cerr << "EdgeId " << edgeId << '\n';
	
	bfs(0, u), bfs(1, v); vector<int> S, T;
	for (int i = 0; i < n; ++i) {
		if (dist[0][i] < dist[1][i]) S.emplace_back(i);
		else if (dist[0][i] > dist[1][i]) T.emplace_back(i);
	}

	// cerr << "S: "; print(S);
	// cerr << "T: "; print(T);

	// for (auto &x : S) cerr << e[x] << ' ';
	// cerr << '\n';
	// for (auto &x : T) cerr << e[x] << ' ';
	// cerr << '\n';

	auto work = [&](const int type, const int root) {
		queue<int> q; memset(dep, -1, sizeof dep);
		q.emplace(root), dep[root] = 0; int cnt = 0;
		for (int i = 0; i < m; ++i) edge[i] = -1, ver[i] = -1;
		while (!q.empty()) {
			int u = q.front(); q.pop();
			for (auto [v, id] : adj[u]) {
				if (dist[type][v] < dist[!type][v]) {
					if (dep[v] == -1) {
						dep[v] = dep[u] + 1;
						ver[cnt] = v, edge[id] = cnt++;
						q.emplace(v);
					}
					else if (dep[v] == dep[u] + 1) {
						edge[id] = inf;
					}
				}
				else if (id != edgeId) edge[id] = inf;
			}
		}

		auto check = [&](int mid) {
			vector<int> w(m, HEAVY);
			for (int i = 0; i < m; ++i) w[i] = edge[i] >= mid;
			// cerr << "check " << myask(w) << ' ' << 1ll * numEdges * A + 1ll * (1 + dist[type][ve[mid]]) * (B - A) << '\n';
			return myask(w) != fixed;
		};

		// for (int i = 0; i < ve.size(); ++i) cerr << check(i);
		// cerr << '\n';
		// for (int i = 0; i < cnt; ++i) cerr << check(i);
		// cerr << '\n';

		int low = 0, high = cnt - 1, id = -1;
		while (low <= high) {
			int mid = low + high >> 1; 
			// if (mid == 1) cerr << "myask = " << myask(w) << '\n';
			// if (type == 0) cerr << mid << ' ' << myask(w) << '\n';
			if (check(mid)) low = (id = mid) + 1;
			else high = mid - 1;
		}
		// cerr << "id = " << id << '\n';
		return (id == -1 ? root : ver[id]);
	};

	int s = work(0, u), t = work(1, v);
	answer(s, t);
}
 
#ifdef hwe
signed main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
 
    #ifdef hwe
        freopen("input.inp", "r", stdin);
        freopen("output.out", "w", stdout);
    #else
        #define taskname ""
        if (fopen(taskname".inp", "r")) {
            freopen(taskname".inp", "r", stdin);
            freopen(taskname".out", "w", stdout);
        }
    #endif
 
    for (int _ = 0; _ < 1000; ++_) {
	    Grader::rand(); Grader::show();
	    int n = Grader::n; vector<int> U, V;
	    for (int i = 0; i < Grader::m; ++i) {
	    	int u, v; tie(u, v) = Grader::edges[i];
	    	U.emplace_back(u), V.emplace_back(v);
	    }
	    find_pair(n, U, V, 1, 2);    	
    }

    Grader::get(); Grader::show();
    int n = Grader::n; vector<int> U, V;
    for (int i = 0; i < Grader::m; ++i) {
    	int u, v; tie(u, v) = Grader::edges[i];
    	U.emplace_back(u), V.emplace_back(v);
    }
    find_pair(n, U, V, 1, 2);
 
    cerr << '\n'; return 0;
}
#endif

Compilation message

highway.cpp: In function 'void find_pair(int, std::vector<int>, std::vector<int>, int, int)':
highway.cpp:200:17: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  200 |   int mid = low + high >> 1; vector<int> w(m, LIGHT);
      |             ~~~~^~~~~~
highway.cpp: In lambda function:
highway.cpp:258:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  258 |    int mid = low + high >> 1;
      |              ~~~~^~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 5712 KB Output is correct
2 Correct 2 ms 5712 KB Output is correct
3 Correct 2 ms 5712 KB Output is correct
4 Correct 2 ms 5712 KB Output is correct
5 Correct 2 ms 5712 KB Output is correct
6 Correct 2 ms 5712 KB Output is correct
7 Correct 2 ms 5712 KB Output is correct
8 Correct 3 ms 5712 KB Output is correct
9 Correct 3 ms 5752 KB Output is correct
10 Correct 2 ms 5712 KB Output is correct
11 Correct 2 ms 5712 KB Output is correct
12 Correct 2 ms 5712 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5712 KB Output is correct
2 Correct 12 ms 7612 KB Output is correct
3 Correct 117 ms 26624 KB Output is correct
4 Correct 117 ms 28632 KB Output is correct
5 Correct 142 ms 27528 KB Output is correct
6 Correct 107 ms 24000 KB Output is correct
7 Correct 126 ms 28576 KB Output is correct
8 Correct 145 ms 28284 KB Output is correct
9 Correct 110 ms 26276 KB Output is correct
10 Correct 147 ms 26884 KB Output is correct
11 Correct 117 ms 28748 KB Output is correct
12 Correct 128 ms 29140 KB Output is correct
13 Correct 150 ms 28040 KB Output is correct
14 Correct 118 ms 27804 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 7760 KB Output is correct
2 Correct 25 ms 10192 KB Output is correct
3 Correct 49 ms 12512 KB Output is correct
4 Correct 113 ms 28060 KB Output is correct
5 Correct 115 ms 28736 KB Output is correct
6 Correct 106 ms 27720 KB Output is correct
7 Correct 119 ms 27456 KB Output is correct
8 Correct 110 ms 28688 KB Output is correct
9 Correct 110 ms 28068 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5712 KB Output is correct
2 Correct 14 ms 7868 KB Output is correct
3 Correct 100 ms 21612 KB Output is correct
4 Correct 106 ms 25520 KB Output is correct
5 Correct 110 ms 26192 KB Output is correct
6 Correct 103 ms 24368 KB Output is correct
7 Correct 108 ms 25472 KB Output is correct
8 Correct 104 ms 24444 KB Output is correct
9 Correct 130 ms 28768 KB Output is correct
10 Correct 130 ms 29084 KB Output is correct
11 Correct 122 ms 27808 KB Output is correct
12 Correct 122 ms 28420 KB Output is correct
13 Correct 128 ms 28488 KB Output is correct
14 Correct 134 ms 29140 KB Output is correct
15 Correct 110 ms 25196 KB Output is correct
16 Correct 120 ms 24600 KB Output is correct
17 Correct 137 ms 28140 KB Output is correct
18 Correct 122 ms 28104 KB Output is correct
19 Correct 117 ms 25240 KB Output is correct
20 Correct 122 ms 28572 KB Output is correct
21 Correct 113 ms 24764 KB Output is correct
22 Correct 122 ms 25228 KB Output is correct
23 Correct 135 ms 29756 KB Output is correct
24 Correct 128 ms 29952 KB Output is correct
25 Correct 130 ms 28392 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 8016 KB Output is correct
2 Correct 16 ms 8188 KB Output is correct
3 Incorrect 137 ms 30388 KB Output is incorrect: {s, t} is wrong.
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 8008 KB Output is correct
2 Correct 15 ms 8264 KB Output is correct
3 Incorrect 169 ms 31840 KB Output is incorrect: {s, t} is wrong.
4 Halted 0 ms 0 KB -