제출 #709839

#제출 시각아이디문제언어결과실행 시간메모리
709839activedeltorreFrom Hacks to Snitches (BOI21_watchmen)C++14
100 / 100
2202 ms137420 KiB
#include <bits/stdc++.h>
#define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x)
#define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x)
typedef long long ll;
typedef std::pair<int, int> pii;
typedef std::pair<ll , ll > pll;
using namespace std;
 
const int N = 250'010;
const int L = 300;
bool has_watch[N];
int watch_size[N];
int watch_ind[N];
int watch_guard[N];
 
int watch_size_list[L];
 
int n, m, k;
 
int *nxt[L][L];
 
void calc_nxt(int step, int size)
{
	if (nxt[step][size])
		return;
	nxt[step][size] = new int[size];
	int cnt = 0;
	for (int beg=0; cnt < size; ++beg) {
		vector<pii> vec;
		int x = beg;
		do {
			while (vec.size() && vec.back().first > x)
				vec.pop_back();
			nxt[step][size][x] = vec.size()?
					cnt - vec.back().second:
					-1;
			vec.push_back({x, cnt});
			++cnt;
			x = x-step%size;
			x = x<0?x+size:x;
		} while (x != beg);
	}
}
 
vector<int> A[N];
int norm_dis[N];
 
void bfs(int s)
{
	memset(norm_dis, -1, sizeof(norm_dis));
	vector<int> q = {s};
	Loop (i,0,q.size()) {
		int v = q[i];
		for (int u : A[v]) {
			if (norm_dis[u] != -1)
				continue;
			norm_dis[u] = norm_dis[v] + 1;
			q.push_back(u);
		}
	}
}
 
vector<ll> dis[N];
 
void upS(int from, int v, ll d, set<tuple<ll,int,int>> &Set)
{
	int md = has_watch[v]? d % watch_size[v]: 0;
	if (d >= dis[v][md])
		return;
	if (has_watch[v] && md == watch_ind[v])
		return;
	if (has_watch[from] && has_watch[v] && watch_guard[from] == watch_guard[v] && watch_ind[from] == md && (watch_ind[v] == md-1 || watch_ind[v] == md+watch_size[v]-1))
		return;
	Set.erase ({dis[v][md]+norm_dis[v], md, v});
	dis[v][md] = d;
	Set.insert({dis[v][md]+norm_dis[v], md, v});
}
 
void up3(int v, int u, ll d, set<tuple<ll,int,int>> &Set)
{
	int step = watch_size[v];
	int size = watch_size[u];
	int x = (d + size - watch_ind[u]) % size;
	for (;;) {
		upS(v, u, d+1, Set);
		ll cnt = nxt[step][size][x];
		if (cnt == -1)
			break;
		d += cnt*step;
		x = (x + cnt*step) % size;
	}
}
 
ll dij(int s, int t)
{
	set<tuple<ll,int,int>> Set;
	Loop (i,0,N)
		dis[i] = vector<ll>(has_watch[i]?watch_size[i]:1, (ll)1e17);
	dis[s][0] = 0;
	Set.insert({dis[s][0]+norm_dis[s], 0, s});
	while (Set.size()) {
		auto [dard, md, v] = *Set.begin();
		Set.erase(Set.begin());
		ll d = dis[v][md];
		if (v == t)
			return d;
		upS(v, v, d+1, Set);
		for (int u : A[v]) {
			if (has_watch[u] && has_watch[v]) {
				up3(v, u, d, Set);
			} else if (has_watch[u]) {
				upS(v, u, d+1, Set);
				int wait = watch_ind[u] - d%watch_size[u];
				wait = wait<0?wait+watch_size[u]:wait;
				upS(v, u, d+1+wait, Set);
			} else {
				upS(v, u, d+1, Set);
			}
		}
	}
	return -1;
}
 
int main()
{
	cin.tie(0) -> sync_with_stdio(false);
	cin >> n >> m;
	Loop (i,0,m) {
		int v, u;
		cin >> v >> u;
		--v; --u;
		A[v].push_back(u);
		A[u].push_back(v);
	}
	cin >> k;
	Loop (i,0,k) {
		int l;
		cin >> l;
		watch_size_list[i] = l;
		Loop (j,0,l) {
			int v;
			cin >> v;
			--v;
			watch_size[v] = l;
			watch_ind[v] = j;
			has_watch[v] = 1;
			watch_guard[v] = i;
		}
	}
	Loop (i,0,k) Loop (j,0,k)
		calc_nxt(watch_size_list[i], watch_size_list[j]);
	bfs(n-1);
	ll ans = dij(0, n-1);
	if (ans == -1)
		cout << "impossible\n";
	else
		cout << ans << '\n';
}

컴파일 시 표준 에러 (stderr) 메시지

watchmen.cpp: In function 'll dij(int, int)':
watchmen.cpp:102:8: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  102 |   auto [dard, md, v] = *Set.begin();
      |        ^
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...