比赛 2026.5.16 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 不是一道路径查询问题 最终得分 100
用户昵称 xuyuqing 运行时间 2.269 s
代码语言 C++ 内存使用 16.48 MiB
提交时间 2026-05-16 09:26:04
显示代码纯文本

#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>

using namespace std;

const int N = 100010;
const int BitLen = 61;

int n;
int m;
int q;
long long V;

namespace Union_Find {
    int dad[BitLen + 1][N];
    int siz[BitLen + 1][N];
    
    void init () {
        for (int line = 0; line <= BitLen; line++) {
            for (int id = 1; id <= n; id++) {
                dad[line][id] = id;
                siz[line][id] = 1;
            }
        }
    }

    int find (int line, int id) {
        if (dad[line][id] == id) {
            return id;
        }
        dad[line][id] = find (line, dad[line][id]);
        return dad[line][id];
    }

    void merge (int line, int one, int two) {
        one = find (line, one);
        two = find (line, two);
        
        if (one == two) {
            return;
        }
    
        if (siz[line][one] > siz[line][two]) {
            siz[line][one] += siz[line][two];
            dad[line][two] = dad[line][one];
        }
        else {
            siz[line][two] += siz[line][one];
            dad[line][one] = dad[line][two];
        }
    }

    bool same (int line, int one, int two) {
        return find (line, one) == find (line, two);
    }  
}

int main () {
    
    freopen ("Paths.in", "r", stdin);
    freopen ("Paths.out", "w", stdout);
    
    scanf ("%d %d %d %lld", &n, &m, &q, &V);
    
    Union_Find::init ();
    
    for (int i = 1; i <= m; i++) {
        int u, v;
        long long w;
        
        scanf ("%d %d %lld", &u, &v, &w);
        
        int j = BitLen - 1;
        for (; (1ll << j) > V; j--) {
            if (w & (1ll << j)) {
                Union_Find::merge (j, u, v);
            }
        }
        for (; j >= 0; j--) {
            if ((1ll << j) & V) {
                if (! ((1ll << j) & w)) {
                    break;
                }
                continue;
            }
            
            if ((1ll << j) & w) {
                Union_Find::merge (j, u, v); 
            }
        }
        if ((w & V) == V) {
            Union_Find::merge (BitLen, u, v);
        }
    }
    
    for (int i = 1; i <= q; i++) {
        int u, v;
        scanf ("%d %d", &u, &v);
        
        bool flag = false;
        
        for (int j = BitLen - 1; j >= 0; j--) {
            if (Union_Find::same (j, u, v)) {
                flag = true;
                break;
            }
        }
        if (Union_Find::same (BitLen, u, v)) {
            flag = true;
        }
        
        if (flag) {
            printf ("Yes\n");
            continue;
        }
        
        printf ("No\n");
    }
    
    return 0;
}