QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#97601#6330. XOR Reachabletom0727RE 572ms182760kbC++148.4kb2023-04-17 12:20:552023-04-17 12:20:57

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-17 12:20:57]
  • 评测
  • 测评结果:RE
  • 用时:572ms
  • 内存:182760kb
  • [2023-04-17 12:20:55]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#if __cplusplus >= 201103L
    struct pairhash {
        static uint64_t splitmix64(uint64_t x) {
            x += 0x9e3779b97f4a7c15;
            x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
            x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
            return x ^ (x >> 31);
        }

        template<class T, class U>
        size_t operator() (const pair<T,U> &p) const {
            static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
            return splitmix64(p.first + FIXED_RANDOM) ^ splitmix64(p.second+ FIXED_RANDOM);
        }
    };
    struct custom_hash {
        static uint64_t splitmix64(uint64_t x) {
            x += 0x9e3779b97f4a7c15;
            x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
            x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
            return x ^ (x >> 31);
        }

        size_t operator()(uint64_t x) const {
            static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
            return splitmix64(x + FIXED_RANDOM);
        }
    };
    mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
    inline int randint(int l, int r) {
        return uniform_int_distribution<int>(l,r)(rng);
    }
    inline double randdouble(double l, double r) {
        return uniform_real_distribution<double>(l,r)(rng);
    }
#endif
 
#ifndef ONLINE_JUDGE
#  define LOG(x) (cerr << #x << " = " << (x) << endl)
#else
#  define LOG(x) 0
#endif

#define fastio ios::sync_with_stdio(false); cin.tie(0);
#define ll long long
#define ull unsigned long long
#define ll128 __int128_t
#define PI 3.14159265358979323846
#define abs(a) ((a>0)?a:-(a))
#define pii pair<int,int>
#define pll pair<ll,ll>

const long double pi = acos(-1.0);
const long double eps = (double)1e-8;

const int mod = 1e9+7;

template<class T>
T qpow(T a, int b) {
    T res = 1;
    while (b) {
        if (b & 1) res *= a;
        a *= a;
        b >>= 1;
    }
    return res;
}
int norm(int x) {
    if (x < 0) {
        x += mod;
    }
    if (x >= mod) {
        x -= mod;
    }
    return x;
}
struct Z {
    int x;
    Z(int x = 0) : x(norm(x)) {}
    Z(ll x) : x(norm((int)(x % mod))) {}
    int val() const {
        return x;
    }
    Z operator-() const {
        return Z(norm(mod - x));
    }
    Z inv() const {
        assert(x != 0);
        return qpow(*this, mod - 2);
    }
    Z &operator*=(const Z &rhs) {
        x = (ll)(x) * rhs.x % mod;
        return *this;
    }
    Z &operator+=(const Z &rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z &operator-=(const Z &rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z &operator/=(const Z &rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator*(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator+(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator-(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator/(const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream &operator>>(std::istream &is, Z &a) {
        ll v;
        is >> v;
        a = Z(v);
        return is;
    }
    friend std::ostream &operator<<(std::ostream &os, const Z &a) {
        return os << a.val();
    }
};

const int maxn = 1e5+5;
const int maxm = 1e5+55;

int n, m, K, Q;
struct Edge {
    int from, to, w;
};
vector<Edge> adj[maxn];

struct State {
    int u, v, szu, szv;
} st[maxm];

struct Query {
    int D, id;
    bool operator<(const Query& other) const {
        return D < other.D;
    }
} q[maxn];
int res[maxn];

int par[maxn], sz[maxn], tail = 0;
ll ans = 0;
ll cal(ll x) {
    return x*(x-1) / 2;
}
inline void init() {
    for (int i = 1; i <= n; i++) par[i] = i, sz[i] = 1;
    tail = 0;
}

int finds(int u) {
    if (par[u] == u) return u;
    return finds(par[u]);
}

void unions(int u, int v) {
    u = finds(u), v = finds(v);
    if (sz[u] < sz[v]) swap(u,v);  // sz[u] >= sz[v]
    st[++tail] = {u, v, sz[u], sz[v]};
    if (u == v) return;
    par[v] = u;
    ans = ans - cal(sz[u]) - cal(sz[v]) + cal(sz[u] + sz[v]);
    sz[u] += sz[v];
    // printf("Unions: u = %d, v = %d, ans = %lld\n", u, v, ans);
}

void cancel() {
    if (tail > 0) {
        int u = st[tail].u, v = st[tail].v;
        par[v] = v;
        if (sz[u] != st[tail].szu) {
            assert(sz[u] == st[tail].szu + st[tail].szv);
            ans = ans - cal(sz[u]) + cal(st[tail].szu) + cal(st[tail].szv);
        }
        sz[u] = st[tail].szu;
        sz[v] = st[tail].szv;
        tail--;
    }
}


struct Node {
    int cnt = 0;
    int child[2];
    vector<Edge> vec;
    vector<int> que;  // queries 的编号
};

// int mask[33];
// bitset<30> mask;
const int M = 30;
bool tag[33];
struct Trie01 {
    int id = 1;  // 注意,从 1 开始
    Node trie[maxn<<4];

    void insert(Edge e) {
        int x = e.w;
        int c = 1;
        for (int j = M; j >= 0; j--) {
            int k = 0;
            if (x & (1<<j)) k = 1;
            if (!trie[c].child[k]) trie[c].child[k] = ++id;
            c = trie[c].child[k];
            trie[c].cnt++;
            trie[c].vec.push_back(e);
        }
        // printf("w = %d, c = %d, e = {%d, %d}\n",e.w,c,e.from,e.to);
    }

    void insert(int x, int i) {
        int c = 1;
        for (int j = M; j >= 0; j--) {
            int k = 0;
            if (x & (1<<j)) k = 1;
            if (!trie[c].child[k]) trie[c].child[k] = ++id;
            c = trie[c].child[k];
            trie[c].cnt++;
        }
        // printf("x = %d, c = %d, i = %d\n",x,c,i);
        trie[c].que.push_back(i);  // 只保留叶子即可
    }

    void addall(int u) {
        for (Edge e : trie[u].vec) {
            // printf("u = %d, e = {%d, %d}, w = %d\n", u, e.from, e.to, e.w);
            unions(e.from, e.to);
        }
    }

    void clearall(int u) {
        for (int i = 0; i < trie[u].vec.size(); i++) cancel();
    }

    // 从 d = M 开始 dfs
    void dfs(int u, int d) {
        if (!u) return;
        // printf("DFS, u = %d, d = %d\n", u, d);
        if (d == -1) {  // 走完了,开始统计答案
            // addall(u);
            for (int id : trie[u].que) res[id] = ans;
            // clearall(u);
            return;
        }
        // 说明这个肯定不为空
        int c[2];
        c[0] = trie[u].child[0], c[1] = trie[u].child[1];

        if (tag[d]) {  // 需要加一边,然后dfs另外一边
            // printf("u = %d, child = {%d, %d}\n",u,c[0],c[1]);
            for (int o = 0; o < 2; o++) {
                addall(c[o^1]);
                // LOG(c[o]);
                dfs(c[o], d-1);
                // mask[d] = o ^ tag[d];
                clearall(c[o^1]);
            }
        } else {
            // mask[d] = 0;
            dfs(c[0], d-1);
            dfs(c[1], d-1);
        }
    }


    // // 求 trie中的一个数 a_i, 使得 a_i ^ x 最大
    // int query(int x) {
    //     int c = 1;
    //     int res = 0;
    //     for (int j = maxm; j >= 0; j--) {
    //         int k = 0;
    //         if (x & (1<<j)) k = 1;
    //         k ^= 1;
    //         if (trie[c].child[k]) {
    //             c = trie[c].child[k];
    //             res |= (1<<j);
    //         } else {
    //             c = trie[c].child[k^1];
    //         }
    //     }
    //     return res;
    // }
} tr;


int main() {
    fastio;
    cin >> n >> m >> K;
    // memset(mask, -1, sizeof(mask));
    for (int i = 1; i <= m; i++) {
        int u, v, w; cin >> u >> v >> w;
        adj[u].push_back({u,v,w});
        adj[v].push_back({v,u,w});
        tr.insert({u,v,w});
    }
    cin >> Q;
    for (int i = 1; i <= Q; i++) {
        cin >> q[i].D;
        q[i].D ^= K;
        // q[i].id = i;
        tr.insert(q[i].D, i);
    }
    // sort(q+1, q+Q+1, [](auto a, auto b) {
    //     return a.D < b.D;
    // });
    init();
    for (int i = M; i >= 0; i--) tag[i] = (K & (1<<i));

    tr.dfs(1, M);
    for (int i = 1; i <= Q; i++) cout << res[i] << "\n";
}

詳細信息

Test #1:

score: 100
Accepted
time: 18ms
memory: 109308kb

input:

4 5 5
1 2 17
1 3 4
2 3 20
2 4 3
3 4 5
4
0
7
16
167

output:

2
6
3
0

result:

ok 4 number(s): "2 6 3 0"

Test #2:

score: 0
Accepted
time: 11ms
memory: 109308kb

input:

9 13 488888932
2 7 771479959
3 8 783850182
5 7 430673756
6 8 350738034
4 9 400768807
2 3 83653266
1 2 829786563
5 8 357613791
7 9 579696618
3 7 423191200
3 5 867380255
1 9 907715012
6 9 1033650694
8
498260055
144262908
117665696
848664012
983408133
32610599
478007408
134182829

output:

16
7
5
13
13
16
16
5

result:

ok 8 numbers

Test #3:

score: 0
Accepted
time: 545ms
memory: 182284kb

input:

446 99235 764320136
1 2 467639025
1 39 240791819
1 197 320023434
1 391 968343602
1 116 841220144
1 345 697806443
1 409 489643820
1 339 733516272
1 89 560099922
1 431 722346703
1 433 246809211
1 344 769002876
1 234 597076758
1 178 505730391
1 75 826728597
1 74 14756981
1 63 280238017
1 288 638627144
...

output:

99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
99235
...

result:

ok 100000 numbers

Test #4:

score: 0
Accepted
time: 572ms
memory: 182760kb

input:

443 100000 587238331
315 322 662401332
43 315 536337643
315 404 1008807430
140 315 116993236
315 349 456757176
315 421 208121145
222 315 165949374
315 359 652820576
128 315 366321131
219 315 385302776
279 315 758612678
315 369 524221824
315 418 405097334
315 344 159069559
114 315 1020799146
36 315 4...

output:

97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
97903
...

result:

ok 100000 numbers

Test #5:

score: -100
Runtime Error

input:

446 99235 319005349
63 98 45774435
98 419 537824294
55 98 970456100
98 295 177258162
98 148 503686739
98 355 952389094
98 110 672181282
98 113 718706403
98 222 193797576
79 98 367361921
8 98 82995994
13 98 401334976
98 427 695043885
98 366 595065071
98 161 581346320
98 128 792799449
98 178 566239903...

output:


result: