Problem:
タクシー 2 (Taxis 2)
問題文
IOI 国には，
1
から
N
までの番号が付けられた
N
個の町と，
1
から
M
までの番号が付けられた
M
本の道がある．
それぞれの道は，タクシーでのみ通行可能である．道
i
(
1 ≦ i ≦ M
) のタクシーは町
A
i
と町
B
i
を
双方向に
移動でき，そのタクシーの色は，
C
i
= 1
のとき赤色，
C
i
= 2
のとき青色である．タクシーには料金がかかり，乗車すると以下のように所持金が変化する．
乗車前の所持金を
a
円とする．
タクシーが赤色の場合，乗車後の所持金が
a - 1
円になる．
タクシーが青色の場合，乗車後の所持金が「
a ÷ 2
を整数に切り捨てた値」円になる．
あなたは IOI 国の町
1
に住んでおり，以下の
Q
個の質問の答えを知っておきたい．
j
番目 (
1 ≦ j ≦ Q
) の質問は以下の通りである．
町
1
から出発し，
1
円以上の所持金を残した状態で
町
T
j
に到着するために，最初に少なくとも何円の所持金を持っている必要があるか．ただし，答えが
L
円よりも大きい場合は，代わりに
Large
と答えよ．
町とタクシーの情報，そして質問の内容が与えられたとき，すべての質問に答えるプログラムを作成せよ．
制約
2 ≦ N ≦ 200000
．
N - 1 ≦ M ≦ 200000
．
1 ≦ Q ≦ 200000
．
1 ≦ L ≦ 1 000 000 000
．
1 ≦ A
i
＜ B
i
≦ N
(
1 ≦ i ≦ M
)．
(A
i
, B
i
) ≠ (A
j
, B
j
)
(
1 ≦ i ＜ j ≦ M
)．
1 ≦ C
i
≦ 2
(
1 ≦ i ≦ M
)．
2 ≦ T
j
≦ N
(
1 ≦ j ≦ Q
)．
どの町の間も，いくつかの道を通って行き来できる．
入力される値はすべて整数である．
入力
入力は以下の形式で標準入力から与えられる．
N
M
Q
L
A
1
B
1
C
1
A
2
B
2
C
2
:
A
M
B
M
C
M
T
1
T
2
:
T
Q
出力
標準出力に
Q
行で出力せよ．
j
行目 (
1 ≦ j ≦ Q
) には，
j
番目の質問の答えを出力せよ．
入出力例
入力例 1
7 6 1 10
1 2 2
2 3 1
3 4 2
4 5 1
5 6 1
6 7 2
5
出力例 1
10
町
1
→ 町
2
→ 町
3
→ 町
4
→ 町
5
の経路で移動するならば，順に青，赤，青，赤のタクシーに乗ることになる．すると，最初に所持金が
10
円あった場合，所持金は
10
円 →
5
円 →
4
円 →
2
円 →
1
円となり，
1
円以上を残した状態で町
5
に到着できる．
一方，最初の所持金が
9
円以下の場合，
1
円以上を残した状態で町
5
に到着することはできない．
入力例 2
10 9 3 25
1 2 2
2 3 1
3 4 1
4 5 1
5 6 2
6 7 1
7 8 1
8 9 1
9 10 2
10
9
3
出力例 2
Large
22
4
例えば，
1
番目の質問について考えよう．
町
1
から出発して町
10
に移動するとき，町
1
→ 町
2
→ … → 町
9
→ 町
10
の経路をたどることになる．しかし，最初に
L (= 25)
円持っていたとしても，タクシーを使うごとに所持金が
25
円 →
12
円 →
11
円 →
10
円 → … と減っていき，
1
円以上を残して町
10
にたどり着くことはできない．よって，
Large
と出力しなければならない．
入力例 3
5 6 1 1000000000
1 4 1
1 5 1
4 5 1
3 4 1
3 5 1
2 3 1
2
出力例 3
4
町
1
→ 町
5
→ 町
3
→ 町
2
の経路で移動するならば，赤いタクシーに
3
回乗ることになる．すると，最初に所持金が
4
円あった場合，所持金は
4
円 →
3
円 →
2
円 →
1
円となり，
1
円以上を残した状態で町
2
に到着できる．
一方，最初の所持金が
3
円以下の場合，
1
円以上を残した状態で町
2
に到着することはできない．
入力例 4
9 11 5 10
1 2 1
1 3 2
2 3 2
2 9 2
3 9 1
4 9 1
8 9 1
5 8 1
5 7 1
4 7 2
6 7 2
2
6
7
8
9
出力例 4
2
Large
7
5
3
情報オリンピック日本委員会
作 『日本情報オリンピック第2回女性部門 本選 競技課題』

Submitted solutions:

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class edge {
public:
	int to, color;
	edge() : to(-1), color(-1) {};
	edge(int to_, int color_) : to(to_), color(color_) {};
};

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	int N, M, Q, L;
	cin >> N >> M >> Q >> L;
	vector<int> A(M), B(M), C(M), T(Q);
	for (int i = 0; i < M; i++) {
		cin >> A[i] >> B[i] >> C[i];
		A[i]--, B[i]--;
	}
	for (int i = 0; i < Q; i++) {
		cin >> T[i];
		T[i]--;
	}
	
	std::vector<int> sep(N + 2);
	for (int i = 0; i < M; i++) {
		sep[A[i] + 2]++;
		sep[B[i] + 2]++;
	}
	for (int i = 0; i < N; i++) {
		sep[i + 2] += sep[i + 1];
	}
	std::vector<edge> edges(2 * M);
	for (int i = 0; i < M; i++) {
		edges[sep[A[i] + 1]++] = edge(B[i], C[i]);
		edges[sep[B[i] + 1]++] = edge(A[i], C[i]);
	}

	const int LAYERS = 30;
	vector<vector<int> > dist(LAYERS, vector<int>(N, L + 1));
	vector<vector<int> > order(LAYERS, vector<int>(N + 1, -1));
	dist[0][0] = 1;
	order[0][0] = 0;
	for (int layer = 0; layer < LAYERS; layer++) {
		vector<int> que(2 * N);
		vector<bool> visited(N, false);
		int ql = 0, qr = 0;
		int ord_index = 0;
		int nord_index = 0;
		while (true) {
			int u = order[layer][ord_index];
			int acost = (u != -1 ? dist[layer][u] : L + 1);
			int bcost = (ql != qr ? dist[layer][que[ql]] : L + 1);
			int ncost = min(acost, bcost) + (1 << layer);
			if (ncost > L) break;
			if (acost > bcost) u = que[ql++];
			else ord_index++;
			if (visited[u]) continue;
			visited[u] = true;
			for (int i = sep[u]; i < sep[u + 1]; i++) {
				edge& e = edges[i];
				if (e.color == 1 && dist[layer][e.to] > ncost) {
					dist[layer][e.to] = ncost;
					que[qr++] = e.to;
				}
				if (e.color == 2 && layer != LAYERS - 1 && dist[layer + 1][e.to] == L + 1) {
					dist[layer + 1][e.to] = ncost;
					order[layer + 1][nord_index++] = e.to;
				}
			}
		}
	}
	
	
	for (int i = 0; i < Q; i++) {
		int answer = L + 1;
		for (int j = 0; j < LAYERS; j++) {
			answer = min(answer, dist[j][T[i]]);
		}
		if (answer <= L) {
			cout << answer << '\n';
		}
		else {
			cout << "Large" << '\n';
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 59384
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i=0;i<n;i++)
#define all(A) A.begin(),A.end()

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N,M,Q,L;
    cin>>N>>M>>Q>>L;
    vector<vector<int>> G(N),H(N);
    rep(i,M){
        int a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        if(c==1){
            G[a].push_back(b);
            G[b].push_back(a);
        }
        else{
            H[a].push_back(b);
            H[b].push_back(a);
        }
    }    
    vector<vector<ll>> D(N,vector<ll>(32,1e9+10));
    D[0][0]=1;
    priority_queue<array<ll,3>,vector<array<ll,3>>,greater<array<ll,3>>> que;
    que.push({1,0,0});
    vector<vector<bool>> seen(N,vector<bool>(32,0));
    while(!que.empty()){
        auto V=que.top();
        que.pop();
        if(seen[V[1]][V[2]])continue;
        seen[V[1]][V[2]]=1;
        for(int v:G[V[1]]){
            if(D[v][V[2]]>V[0]+(1ll<<V[2])){
                D[v][V[2]]=V[0]+(1ll<<V[2]);
                que.push({D[v][V[2]],v,V[2]});
            }
        }
        if(V[2]==31)continue;
        for(int v:H[V[1]]){
            if(D[v][V[2]+1]>V[0]+(1ll<<V[2])){
                D[v][V[2]+1]=V[0]+(1ll<<V[2]);
                que.push({D[v][V[2]+1],v,V[2]+1});
            }
        }
    }
    // rep(i,N)rep(j,3)cout<<i<<" "<<j<<" "<<D[i][j]<<endl;
    rep(q,Q){
        ll T;
        cin>>T;
        T--;
        ll an=L+1;
        rep(j,32)an=min(an,D[T][j]);
        if(an>L)cout<<"Large\n";
        else cout<<an<<"\n";
    }
     
}
accuracy: 1
time_ms: 2140
memory_kb: 93544
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;

#define chmin(x,y) x = min(x,y) // xをyと比較して小さい方に更新
#define chmax(x,y) x = max(x,y) // xをyと比較して大きい方に更新
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000LL // オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001

#define SIZE 200005
#define MAX 30

ll POW[MAX+1];

struct Edge {
    int to;
    bool isBlue;

    Edge(int arg_to, bool arg_isBlue) : to(arg_to), isBlue(arg_isBlue) {}
};

struct State {
    int node, count;
    ll sum_dist;

    State(int arg_node, int arg_count, ll arg_sum_dist) 
        : node(arg_node), count(arg_count), sum_dist(arg_sum_dist) {}

    State() : node(0), count(0), sum_dist(0) {}

    // 優先度キューで最小の距離を得るための比較関数
    bool operator<(const State& arg) const {
        return sum_dist > arg.sum_dist;
    }
};

ll min_dist[MAX+1][SIZE];
vector<Edge> G[SIZE];

int main() {
    // 2の累乗のテーブルを作成
    POW[0] = 1;
    for (int i = 1; i <= MAX; i++) {
        POW[i] = POW[i-1] * 2;
    }

    int N, M, numQ;
    scanf("%d %d %d", &N, &M, &numQ);

    ll L;
    scanf("%lld", &L);

    int a, b, c;
    for (int i = 0; i < M; i++) {
        scanf("%d %d %d", &a, &b, &c);
        a--;
        b--;
        G[a].emplace_back(b, c == 2); // 青い辺かどうかを判定
        G[b].emplace_back(a, c == 2); // 無向グラフ
    }

    // 初期化: すべての最小距離を無限大に設定
    for (int i = 0; i <= MAX; i++) {
        for (int k = 0; k < N; k++) {
            min_dist[i][k] = HUGE_NUM;
        }
    }

    min_dist[0][0] = 1; // 初期状態: 青い辺を通らずにスタート地点にいる場合の最小コスト

    priority_queue<State> Q;
    Q.emplace(0, 0, 1); // 初期状態をキューにプッシュ

    while (!Q.empty()) {
        State state = Q.top();
        Q.pop();

        if (state.sum_dist > min_dist[state.count][state.node]) continue;

        for (const auto& edge : G[state.node]) {
            int next_node = edge.to;
            ll next_dist = state.sum_dist + POW[state.count];
            if (next_dist > L) continue; // 制約条件を満たさない場合はスキップ

            int next_count = state.count;
            if (edge.isBlue) {
                next_count++; // 青い辺を通った回数を更新
            }

            if (min_dist[next_count][next_node] > next_dist) {
                min_dist[next_count][next_node] = next_dist;
                Q.emplace(next_node, next_count, next_dist);
            }
        }
    }

    int tmp_node;
    for (int loop = 0; loop < numQ; loop++) {
        scanf("%d", &tmp_node);
        tmp_node--;

        ll ans = HUGE_NUM;
        for (int i = 0; i <= MAX; i++) {
            chmin(ans, min_dist[i][tmp_node]);
        }

        if (ans == HUGE_NUM) {
            printf("Large\n"); // 到達不可能の場合
        } else {
            printf("%lld\n", ans); // 最小コストを出力
        }
    }

    return 0;
}
accuracy: 1
time_ms: 810
memory_kb: 68472
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 200005
#define MAX 30

ll POW[MAX+1];

struct Edge{
	Edge(int arg_to,bool arg_isBlue){
		to = arg_to;
		isBlue = arg_isBlue;
	}

	int to;
	bool isBlue;
};

struct State{
	State(int arg_node,int arg_count,ll arg_sum_dist){
		node = arg_node;
		count = arg_count;
		sum_dist = arg_sum_dist;
	}
	State(){

		node = count = 0;
		sum_dist = 0;
	}
	bool operator<(const struct State& arg) const{

		return sum_dist > arg.sum_dist;
	}
	int node,count;
	ll sum_dist;

};

ll min_dist[MAX+1][SIZE];
vector<Edge> G[SIZE];


int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	int N,M,numQ;
	scanf("%d %d %d",&N,&M,&numQ);

	ll L;
	scanf("%lld",&L);

	int a,b,c;
	for(int i = 0; i < M; i++){

		scanf("%d %d %d",&a,&b,&c);
		a--;
		b--;

		G[a].push_back(Edge(b,c==2));
		G[b].push_back(Edge(a,c==2));
	}

	for(int i = 0; i <= MAX; i++){
		for(int k = 0; k < N; k++){

			min_dist[i][k] = HUGE_NUM;
		}
	}

	min_dist[0][0] = 1; //min_dist[青い辺を通った回数][現在地] = 最小当初金

	priority_queue<State> Q;
	Q.push(State(0,0,1));

	while(!Q.empty()){

		State state = Q.top();
		Q.pop();

		if(state.sum_dist > min_dist[state.count][state.node])continue;

		for(int i = 0; i < G[state.node].size(); i++){

			int next_node = G[state.node][i].to;
			ll next_dist = state.sum_dist+POW[state.count];
			if(next_dist > L)continue;
			ll next_count = state.count;
			if(G[state.node][i].isBlue){

				next_count++;
			}
			if(min_dist[next_count][next_node] > next_dist){
				min_dist[next_count][next_node] = next_dist;
				Q.push(State(next_node,next_count,next_dist));
			}
		}
	}

	int tmp_node;
	for(int loop = 0; loop < numQ; loop++){

		scanf("%d",&tmp_node);
		tmp_node--;

		ll ans = HUGE_NUM;
		for(int i = 0; i <= MAX; i++){

			chmin(ans,min_dist[i][tmp_node]);
		}
		if(ans == HUGE_NUM){

			printf("Large\n");

		}else{

			printf("%lld\n",ans);
		}
	}


	return 0;
}
accuracy: 1
time_ms: 1460
memory_kb: 63852
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline double time() {
    return static_cast<double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

const ll inf = 2e9;
const int N = 200200;
ll dp[30][N];

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m,q,l; cin >> n >> m >> q >> l;
    vector<vector<int>> g(n),gg(n);
    for(int i=0;i<m;i++){
        int x,y; cin >> x >> y;
        x--; y--;
        int c; cin >> c;
        if(c == 1){
            g[x].push_back(y);
            g[y].push_back(x);
        }
        else{
            gg[x].push_back(y);
            gg[y].push_back(x);
        }
    }
    for(int j=0;j<30;j++){
        for(int k=0;k<n;k++){
            dp[j][k] = inf;
        }
    }
    dp[0][0] = 1;
    priority_queue<pair<ll,pair<int,int>>, vector<pair<ll,pair<int,int>>>, greater<pair<ll,pair<int,int>>>> pq;
    pq.push({1,{0,0}});
    while(pq.size()){
        auto p = pq.top(); pq.pop();
        ll cost = p.first;
        int da = p.second.first;
        int s = p.second.second;
        if(dp[da][s] != cost)continue;
        if(cost >= inf)continue;
        for(int t:g[s]){
            ll ncost = cost + (1<<da);
            if(dp[da][t] > ncost){
                dp[da][t] = ncost;
                pq.push({ncost,{da,t}});
            }
        }
        for(int t:gg[s]){
            if(da == 29)break;
            ll ncost = cost + (1<<da);
            if(dp[da+1][t] > ncost){
                dp[da+1][t] = ncost;
                pq.push({ncost,{da+1,t}});
            }
        }
    }
    while(q--){
        int t; cin >> t; t--;
        ll res = l+1;
        for(int i=0;i<30;i++){
            res = min(res,dp[i][t]);
        }
        if(res > l){
            cout << "Large" << "\n";
        }
        else{
            cout << res << "\n";
        }
    }
}
accuracy: 1
time_ms: 1240
memory_kb: 69232
final_rank: 4

code_snippet: //会津大学オンラインジャッジ問0734Taxis 2に挑戦するコード
//作者堀江
#include <cmath>
#include <iostream>
#include <vector>
#include <string.h>
#include <queue>
using namespace std;

struct E{
	long long int l,mult2,count2;
	int p;
	
	bool operator<(const E& e)const{
		if(l!=e.l)return l>e.l;
		return p<e.p;
	}
};
vector<int> gs1[200003],gs2[200003];
long long int dp[34][200003],ans[200003];
bool first[34][200003];

int main() {
	int n,m,q,l;
	cin>>n>>m>>q>>l;
	for(int j=0;j<34;j++){
		for(int i=1;i<=n;i++){
			first[j][i]=true;
			dp[j][i]=l+1;
			ans[i]=l+1;
		}
	}
	for(int i=0;i<m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		if(c==1){
			gs1[a].push_back(b);
			gs1[b].push_back(a);
		}else{
			gs2[a].push_back(b);
			gs2[b].push_back(a);
		}
	}
	for(int i=0;i<34;i++){
		dp[i][1]=0;
	}
	ans[1]=0;
	E e1;
	e1.p=1;
	e1.l=0;
	e1.count2=0;
	e1.mult2=1;
	priority_queue<E> pq;
	pq.push(e1);
	while(pq.size()>0){
		e1=pq.top();
		pq.pop();
		//cout<<e1.p<<" l="<<e1.l<<" m2="<<e1.mult2<<" c2"<<e1.count2<<endl;
		if(e1.l+e1.mult2>l)continue;
		if(first[e1.count2][e1.p]==false)continue;
		first[e1.count2][e1.p]=false;
		for(int i=0;i<gs1[e1.p].size();i++){
			E e2;
			e2.p=gs1[e1.p][i];
			e2.l=e1.l+e1.mult2;
			e2.mult2=e1.mult2;
			e2.count2=e1.count2;
			if(dp[e2.count2][e2.p]>e2.l){
				dp[e2.count2][e2.p]=e2.l;
				pq.push(e2);
			}
			if(ans[e2.p]>e2.l+e2.mult2){
				ans[e2.p]=e2.l+e2.mult2;
			}
		}
		for(int i=0;i<gs2[e1.p].size();i++){
			E e2;
			e2.p=gs2[e1.p][i];
			e2.l=e1.l;
			e2.mult2=e1.mult2*2;
			e2.count2=e1.count2+1;
			if(dp[e2.count2][e2.p]>e2.l){
				dp[e2.count2][e2.p]=e2.l;
				pq.push(e2);
			}
			if(ans[e2.p]>e2.l+e2.mult2){
				ans[e2.p]=e2.l+e2.mult2;
			}
		}
	}
	
	
	for(int i=0;i<q;i++){
		int p1;
		cin>>p1;
		if(ans[p1]==l+1){
			cout<<"Large"<<endl;
		}else{
			cout<<ans[p1]<<endl;
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 2190
memory_kb: 147440
final_rank: 8

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,n) for(int i=1;i<=(n);++i)
#define all(x) begin(x),end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a, b) (((a) + (b) - 1) / (b))
using pii = pair<int,int>;
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int_fast64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod1 = 1e9+7;
constexpr int mod2 = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template<class T, class U> istream& operator>>(istream& is, pair<T, U>& p){ is >> p.first >> p.second; return (is); }
template<class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p){ os << p.first << ' ' << p.second; return (os); }
template<class T> istream& operator>>(istream& is, vector<T>& v){ for (auto &&e : v) is >> e; return (is); }
template<class T> ostream& operator<<(ostream& os, vector<T>& v){ for (auto &&e : v) os << e << ' '; return (os); }

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T, vector<T>, greater<T> >;
template <class A, class B> using umap = unordered_map<A, B>;
template <class T> using uset = unordered_set<T>;

template <class T> using Max_Heap = __gnu_pbds::priority_queue<T, less<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Min_Heap = __gnu_pbds::priority_queue<T, greater<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class K, class V> using Umap = __gnu_pbds::gp_hash_table<K, V>;
template <class T> using Rope = __gnu_cxx::rope<T>;
using Trie = __gnu_pbds::trie<string, __gnu_pbds::null_type, __gnu_pbds::trie_string_access_traits<>, __gnu_pbds::pat_trie_tag, __gnu_pbds::trie_prefix_search_node_update>;

template <class T> void bye(T x){ cout << x << '\n'; exit(0); }
inline int square(int a){ return (a * a); }

constexpr int dx[] = {1,0,-1,0,1,1,-1,-1};
constexpr int dy[] = {0,-1,0,1,1,-1,-1,1};

struct UnionFind{
    int n;
    vector<int> data;

    UnionFind(int sz) : n(sz), data(sz, -1){}

    bool unite(int x, int y){
        x = find(x), y = find(y);
        if(x == y) return (false);
        if(data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return (true);
    }

    int find(int k){
        if(data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }

    int size(int k){
        return (-data[find(k)]);
    }

    bool same(int x, int y){
        return (find(x) == find(y));
    }

    vector<vector<int> > groups(){
        vector<int> leader_buf(n), group_size(n);
        for(int i = 0; i < n; ++i){
            leader_buf[i] = find(i);
            group_size[leader_buf[i]]++;
        }
        vector<vector<int> > res(n);
        for(int i = 0; i < n; ++i){
            res[i].reserve(group_size[i]);
        }
        for(int i = 0; i < n; ++i){
            res[leader_buf[i]].emplace_back(i);
        }
        res.erase(
            remove_if(res.begin(), res.end(),
                      [&](const vector<int>& v){ return (v.empty()); }),
            res.end());
        return (res);
    }
};

signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout.setf(ios_base::fixed);
    cout.precision(12);

    int n, m, q, l;
    cin >> n >> m >> q >> l;

    UnionFind uf(n);

    assert(2 <= n && n <= 200000);
    assert(n - 1 <= m && m <= 200000);
    assert(1 <= q && q <= 200000);

    vector<vector<pair<int, int> > > g(n);

    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;

        assert(1 <= a && a < b && b <= n);
        assert(1 <= c && c <= 2);

        --a, --b;

        uf.unite(a, b);

        g[a].emplace_back(b, c);
        g[b].emplace_back(a, c);
    }

    assert(uf.size(0) == n);

    vector<vector<int> > dist(32, vector<int>(n, INF));
    min_heap<tuple<int, int, int> > pq;
    dist[0][0] = 0;
    pq.emplace(0, 0, 0);

    while (!pq.empty()) {
        auto [b, a, cur] = pq.top();
        pq.pop();
        if ((1LL << a) + b > (long long) l) continue;
        if (dist[a][cur] < b) continue;
        for (auto [to, c] : g[cur]) {
            if (c == 1) {
                if (chmin(dist[a][to], dist[a][cur] + (1 << a))) {
                    pq.emplace(dist[a][to], a, to);
                }
            } else {
                if (chmin(dist[a + 1][to], dist[a][cur])) {
                    pq.emplace(dist[a + 1][to], a + 1, to);
                }
            }
        }
    }

    vector<int> res(n, INF);

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < 32; ++j) {
            if ((1LL << j) + dist[j][i] <= (long long) l) {
                chmin(res[i], (1 << j) + dist[j][i]);
            }
        }
    }

    for (int i = 0; i < q; ++i) {
        int t;
        cin >> t;

        assert(2 <= t && t <= n);

        t--;

        if (res[t] > l) {
            cout << "Large\n";
        } else {
            cout << res[t] << '\n';
        }
    }

    return (0);
}
accuracy: 1
time_ms: 1190
memory_kb: 62340
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define drep(i,j,n) for(int i=0;i<(int)(n-1);i++)for(int j=i+1;j<(int)(n);j++)
#define trep(i,j,k,n) for(int i=0;i<(int)(n-2);i++)for(int j=i+1;j<(int)(n-1);j++)for(int k=j+1;k<(int)(n);k++)
#define codefor int test;scanf("%d",&test);while(test--)
#define INT(...) int __VA_ARGS__;in(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define yes(ans) if(ans)printf("yes\n");else printf("no\n")
#define Yes(ans) if(ans)printf("Yes\n");else printf("No\n")
#define YES(ans) if(ans)printf("YES\n");else printf("NO\n")
#define popcount(v) __builtin_popcountll(v)
#define vector2d(type,name,h,...) vector<vector<type>>name(h,vector<type>(__VA_ARGS__))
#define vector3d(type,name,h,w,...) vector<vector<vector<type>>>name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
#define vector4d(type,name,h,w,d,...) vector<vector<vector<vector<type>>>>name(h,vector<vector<vector<type>>>(w,vector<vector<type>>(d,vector<type>(__VA_ARGS__))))
using namespace std;
using ll = long long;
template<class T> using rpriority_queue = priority_queue<T, vector<T>, greater<T>>;
const int MOD=1000000007;
const int MOD2=998244353;
const int INF=1<<30;
const ll INF2=1LL<<60;
void scan(int& a){scanf("%d",&a);}
void scan(long long& a){scanf("%lld",&a);}
template<class T,class L>void scan(pair<T, L>& p){scan(p.first);scan(p.second);}
template<class T,class U,class V>void scan(tuple<T,U,V>& p){scan(get<0>(p));scan(get<1>(p));scan(get<2>(p));}
template<class T, size_t size> void scan(array<T, size>& a){ for(auto&& i : a) scan(i);}
template<class T> void scan(T& a){cin>>a;}
template<class T> void scan(vector<T>& vec){for(auto&& it:vec)scan(it);}
void in(){}
template <class Head, class... Tail> void in(Head& head, Tail&... tail){scan(head);in(tail...);}
void print(const int& a){printf("%d",a);}
void print(const long long& a){printf("%lld",a);}
void print(const double& a){printf("%.15lf",a);}
template<class T,class L>void print(const pair<T, L>& p){print(p.first);putchar(' ');print(p.second);}
template<class T> void print(const T& a){cout<<a;}
template<class T> void print(const vector<T>& vec){if(vec.empty())return;print(vec[0]);for(auto it=vec.begin();++it!= vec.end();){putchar(' ');print(*it);}}
void out(){putchar('\n');}
template<class T> void out(const T& t){print(t);putchar('\n');}
template <class Head, class... Tail> void out(const Head& head,const Tail&... tail){print(head);putchar(' ');out(tail...);}
template<class T> void dprint(const T& a){cerr<<a;}
template<class T> void dprint(const vector<T>& vec){if(vec.empty())return;cerr<<vec[0];for(auto it=vec.begin();++it!= vec.end();){cerr<<" "<<*it;}}
void debug(){cerr<<endl;}
template<class T> void debug(const T& t){dprint(t);cerr<<endl;}
template <class Head, class... Tail> void debug(const Head& head, const Tail&... tail){dprint(head);cerr<<" ";debug(tail...);}
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
ll modinv(ll a, ll m) {ll b = m, u = 1, v = 0;while (b) {ll t = a / b;a -= t * b; swap(a, b);u -= t * v; swap(u, v);}u %= m;if (u < 0) u += m;return u;}
ll updivide(ll a,ll b){return (a+b-1)/b;}
int msb(ll v){return 63-__builtin_clzll(v);}
template<class T> void chmax(T &a,const T b){if(b>a)a=b;}
template<class T> void chmin(T &a,const T b){if(b<a)a=b;}

int main(){
    INT(n,m,q,l);
    vector<vector<pair<int,int>>> g(n);
    int u,v,c;
    rep(i,m){
        in(u,v,c);
        u--,v--;
        g[u].emplace_back(v,c);
        g[v].emplace_back(u,c);
    }
    vector2d(ll,dist,n,32,INF2);
    rpriority_queue<array<ll,3>> pq;
    dist[0][0]=0;
    pq.push({0,0,0});
    while(!pq.empty()){
        auto a=pq.top();
        pq.pop();
        if(a[0]>l||a[2]==31)continue;
        for(auto p:g[a[1]]){
            if(p.second==1){
                if(a[0]+(1<<a[2])>=dist[p.first][a[2]])continue;
                dist[p.first][a[2]]=a[0]+(1<<a[2]);
                pq.push({dist[p.first][a[2]],p.first,a[2]});
            }else{
                if(a[0]>=dist[p.first][a[2]+1])continue;
                dist[p.first][a[2]+1]=a[0];
                pq.push({dist[p.first][a[2]+1],p.first,a[2]+1});
            }
        }
    }
    while(q--){
        in(u);
        u--;
        ll ans=INF2;
        rep(i,31)chmin(ans,dist[u][i]+(1<<i));
        if(ans>l)out("Large");
        else out(ans);
    }
}
accuracy: 1
time_ms: 1860
memory_kb: 116484
final_rank: 7