답안 #1107507

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1107507 2024-11-01T11:08:12 Z thieunguyenhuy 통행료 (IOI18_highway) C++17
51 / 100
149 ms 31644 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(10, 20), m = random(n - 1, 100), 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) {
		for (int i = 0; i < n; ++i) dist[i] = INF;
		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) {
	queue<int> q; q.emplace(root); dist[type][root] = 0;
	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;
	}
  	assert(edgeId != -1);
	int u = U[edgeId], v = V[edgeId];

	// cerr << "EdgeId " << edgeId << '\n';
	
	for (int i : {0, 1}) for (int j = 0; j < n; ++j) {
		dist[i][j] = -1;
	}
	bfs(0, u), bfs(1, v);

	auto work = [&](const int type, const int root) {
		queue<int> q; for (int i = 0; i < n; ++i) dep[i] = -1;
		q.emplace(root), dep[root] = 0; int cnt = 0;
		for (int i = 0; i < m; ++i) edge[i] = 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;
			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; _ < 1000000; ++_) {
    	if (_ % 10000 == 0) cerr << "Doing " << _ << '\n';
	    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, 2, 3);    	
    }

    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:249:18: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  249 |    int mid = low + high >> 1;
      |              ~~~~^~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4688 KB Output is correct
2 Correct 1 ms 4688 KB Output is correct
3 Correct 1 ms 4688 KB Output is correct
4 Correct 2 ms 4688 KB Output is correct
5 Correct 2 ms 4688 KB Output is correct
6 Correct 1 ms 4544 KB Output is correct
7 Correct 2 ms 4688 KB Output is correct
8 Correct 2 ms 4688 KB Output is correct
9 Correct 2 ms 4688 KB Output is correct
10 Correct 2 ms 4860 KB Output is correct
11 Correct 2 ms 4688 KB Output is correct
12 Correct 2 ms 4688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4688 KB Output is correct
2 Correct 12 ms 6828 KB Output is correct
3 Correct 126 ms 26160 KB Output is correct
4 Correct 117 ms 28332 KB Output is correct
5 Correct 129 ms 26808 KB Output is correct
6 Correct 115 ms 23732 KB Output is correct
7 Correct 120 ms 28308 KB Output is correct
8 Correct 116 ms 28052 KB Output is correct
9 Correct 137 ms 25924 KB Output is correct
10 Correct 131 ms 26640 KB Output is correct
11 Correct 149 ms 28508 KB Output is correct
12 Correct 131 ms 28748 KB Output is correct
13 Correct 147 ms 27680 KB Output is correct
14 Correct 125 ms 27492 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 6736 KB Output is correct
2 Correct 25 ms 9292 KB Output is correct
3 Correct 41 ms 11664 KB Output is correct
4 Correct 118 ms 27828 KB Output is correct
5 Correct 120 ms 28204 KB Output is correct
6 Correct 125 ms 27564 KB Output is correct
7 Correct 122 ms 26988 KB Output is correct
8 Correct 115 ms 28232 KB Output is correct
9 Correct 125 ms 27812 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4688 KB Output is correct
2 Correct 16 ms 6992 KB Output is correct
3 Correct 92 ms 20796 KB Output is correct
4 Correct 108 ms 25280 KB Output is correct
5 Correct 113 ms 25760 KB Output is correct
6 Correct 107 ms 24008 KB Output is correct
7 Correct 134 ms 25260 KB Output is correct
8 Correct 102 ms 24196 KB Output is correct
9 Correct 121 ms 28356 KB Output is correct
10 Correct 119 ms 28780 KB Output is correct
11 Correct 125 ms 27400 KB Output is correct
12 Correct 114 ms 28040 KB Output is correct
13 Correct 125 ms 28332 KB Output is correct
14 Correct 128 ms 28972 KB Output is correct
15 Correct 113 ms 24940 KB Output is correct
16 Correct 111 ms 24136 KB Output is correct
17 Correct 124 ms 27868 KB Output is correct
18 Correct 122 ms 27732 KB Output is correct
19 Correct 104 ms 24920 KB Output is correct
20 Correct 116 ms 28160 KB Output is correct
21 Correct 111 ms 24260 KB Output is correct
22 Correct 120 ms 24768 KB Output is correct
23 Correct 135 ms 29124 KB Output is correct
24 Correct 130 ms 29696 KB Output is correct
25 Correct 132 ms 27852 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 6992 KB Output is correct
2 Correct 16 ms 7248 KB Output is correct
3 Incorrect 143 ms 30260 KB Output is incorrect: {s, t} is wrong.
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 6992 KB Output is correct
2 Correct 16 ms 7248 KB Output is correct
3 Incorrect 144 ms 31644 KB Output is incorrect: {s, t} is wrong.
4 Halted 0 ms 0 KB -