QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#877520#3086. Edge SubsetsohwphilWA 0ms3584kbC++177.6kb2025-01-31 22:59:132025-01-31 22:59:13

Judging History

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

  • [2025-01-31 22:59:13]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3584kb
  • [2025-01-31 22:59:13]
  • 提交

answer

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

typedef long long ll;

ll N, M, A, B;
ll G;
ll inv_A;

ll MOD = 119<<23|1;

vector<vector<ll>> adj;

// modular inverse with egcd
// get a^-1LL mod b
ll Modinverse(ll a, ll b) {
    ll r0 = a, r1LL = b;
    ll t0 = 1LL, t1LL = 0;
    while (r1LL) {
        ll q = r0 / r1LL;
        ll r = r0 - q * r1LL;
        ll t = t0 - q * t1LL;
        r0 = r1LL; r1LL = r;
        t0 = t1LL; t1LL = t;
    }
    t0 = (t0 % b + b) % b;
    return t0;
}

ll get_dp(ll height, ll width, vector<vector<ll>>& adj_type1, vector<vector<ll>>& adj_type2) {
    ll bitlen1 = B + 1LL;
    ll bitlen2 = 2 * (height + 1LL);
    ll half_bitlen2 = bitlen2 / 2;

    if (bitlen1 <= bitlen2) {
        vector<ll> dp(1LL << bitlen1, 0);
        dp[0] = 1LL;
        for (ll i = 0; i < adj_type1.size(); ++i) {
            vector<ll> new_dp(1LL << bitlen1, 0);
            for (ll prev_mask = 0; prev_mask < (1LL << bitlen1); ++prev_mask) {
                if (dp[prev_mask] == 0) {
                    continue;
                }
                // transition without connecting the current point
                new_dp[prev_mask >> 1LL] = (new_dp[prev_mask >> 1LL] + dp[prev_mask]) % MOD;
                // transition with connecting the current point
                for (auto next : adj_type1[i]) {
                    ll pos_diff = i - next;
                    if (prev_mask & (1LL << (bitlen1 - pos_diff))) {
                        continue;
                    }
                    ll next_mask = (prev_mask >> 1LL) | (1LL << (bitlen1 - 1LL));
                    if (bitlen1 - pos_diff > 0) {
                        next_mask |= (1LL << (bitlen1 - pos_diff - 1LL));
                    }
                    new_dp[next_mask] = (new_dp[next_mask] + dp[prev_mask]) % MOD;
                }
            }
            dp = new_dp;
        }
        ll ans = 0;
        for (auto x : dp) {
            ans = (ans + x) % MOD;
        }
        return ans;
    }
    else {
        vector<ll> dp(1LL << bitlen2, 0);
        dp[0] = 1LL;
        for (ll i = 0; i < half_bitlen2; ++i) {
            vector<ll> new_dp(1LL << bitlen2, 0);
            // half mask. 
            for (ll prev_mask = 0; prev_mask < (1LL << half_bitlen2); ++prev_mask) {
                if (dp[prev_mask | (prev_mask << half_bitlen2)] == 0) {
                    continue;
                }
                ll prev_complete_mask = prev_mask | (prev_mask << half_bitlen2);
                ll next_mask = prev_mask >> 1LL;
                ll next_complete_mask = next_mask | (next_mask << half_bitlen2);
                // transition without connecting the current point
                new_dp[next_complete_mask] = (new_dp[next_complete_mask] + dp[prev_complete_mask]) % MOD;
                // transition with connecting the current point
                for (auto next : adj_type2[i]) {
                    ll pos_diff = i - next;
                    if (prev_mask & (1LL << (half_bitlen2 - pos_diff))) {
                        continue;
                    }
                    ll next_mask = (prev_mask >> 1LL) | (1LL << (half_bitlen2 - 1LL));
                    if (half_bitlen2 - pos_diff > 0) {
                        next_mask |= (1LL << (half_bitlen2 - pos_diff - 1LL));
                    }
                    new_dp[next_mask | (next_mask << half_bitlen2)] = (new_dp[next_mask | (next_mask << half_bitlen2)] + dp[prev_complete_mask]) % MOD;
                }
            }
            dp = new_dp;
        }
        for (ll i = half_bitlen2; i < adj_type2.size(); ++i) {
            vector<ll> new_dp(1LL << bitlen2, 0);
            // half mask. 
            for (ll prev_mask = 0; prev_mask < (1LL << bitlen2); ++prev_mask) {
                if (dp[prev_mask] == 0) {
                    continue;
                }
                // represents the first half_bitlen2 bits of the mask : first elements
                ll upper_mask = prev_mask >> half_bitlen2;
                // represents the part where we're looking at
                ll lower_mask = prev_mask & ((1LL << half_bitlen2) - 1LL);
                // transition without connecting the current point
                new_dp[(upper_mask << half_bitlen2) | (lower_mask >> 1LL)] = (new_dp[(upper_mask << half_bitlen2) | (lower_mask >> 1LL)] + dp[prev_mask]) % MOD;
                // transition with connecting the current point
                for (auto next : adj_type2[i]) {
                    bool is_in_upper = next < half_bitlen2;
                    bool is_in_lower = (i - next) <= half_bitlen2;
                    assert(is_in_upper || is_in_lower);
                    bool is_next_occupied = false;
                    if (is_in_upper && (upper_mask & (1LL << next))) {
                        is_next_occupied = true;
                    }
                    if (is_in_lower && (lower_mask & (1LL << (half_bitlen2 - (i - next))))) {
                        assert(!is_in_upper || is_next_occupied);
                        is_next_occupied = true;
                    }
                    if (is_next_occupied) {
                        continue;
                    }
                    ll next_upper_mask = upper_mask;
                    ll next_lower_mask = lower_mask;
                    if (is_in_upper) {
                        next_upper_mask |= (1LL << next);
                    }
                    if (is_in_lower) {
                        next_lower_mask |= (1LL << (half_bitlen2 - (i - next)));
                    }
                    next_lower_mask >>= 1LL;
                    next_lower_mask |= (1LL << (half_bitlen2 - 1LL));
                    new_dp[(next_upper_mask << half_bitlen2) | next_lower_mask] = (new_dp[(next_upper_mask << half_bitlen2) | next_lower_mask] + dp[prev_mask]) % MOD;
                }
            }
            dp = new_dp;
        }
        ll ans = 0;
        for (auto x : dp) {
            ans = (ans + x) % MOD;
        }
        return ans;
    }

}

pair<ll, ll> get_idx(ll p) {
    p = p / G;
    return {p / B, (p * inv_A) % B};
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    cin >> N >> M >> A >> B;

    adj.resize(N);

    for (ll i = 0; i < M; i++) {
        ll u, v;
        cin >> u >> v;
        --u; --v;
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    G = gcd(A, B);
    A /= G;
    B /= G;
    inv_A = Modinverse(A, B);

    ll ans = 1LL;

    // process points with remainder i when divided by G
    for (ll i = 0; i < G; ++i) {
        vector<ll> points;
        for (ll j = i; j < N; j += G) {
            points.push_back(j);
        }
        ll grid_height = max(2LL, (ll)(points.size() + B - 1LL) / B);
        vector<vector<ll>> adj_2d_type1(grid_height * B, vector<ll>()), adj_2d_type2(grid_height * B, vector<ll>());
        for (ll j = 0; j < points.size(); ++j) {
            auto [idx, jdx] = get_idx(points[j]);
            for (auto next : adj[points[j]]) {
                auto [next_idx, next_jdx] = get_idx(next);
                if (next_idx * B + next_jdx < idx * B + jdx) {
                    adj_2d_type1[idx * B + jdx].push_back(next_idx * B + next_jdx);
                }
                if (next_idx + next_jdx * grid_height < idx + jdx * grid_height) {
                    adj_2d_type2[jdx * grid_height + idx].push_back(next_jdx * grid_height + next_idx);
                }
            }
        }
        ans = ans * get_dp(grid_height, B, adj_2d_type1, adj_2d_type2) % MOD;
    }

    cout << ans << "\n";

    return 0;
}

详细

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 3584kb

input:

50 97 31 32
5 37
15 46
2 33
15 46
6 37
14 46
1 32
2 34
5 36
1 32
5 37
3 35
11 42
12 44
2 33
1 33
10 42
3 35
12 43
14 46
18 49
2 34
1 33
12 43
15 47
13 45
12 44
11 42
9 41
1 32
7 39
3 35
4 35
11 43
11 42
13 45
2 34
12 43
6 38
18 50
3 35
4 36
13 45
17 49
12 43
3 34
15 46
3 34
1 32
11 42
4 35
2 34
10 4...

output:

35804485

result:

wrong answer 1st lines differ - expected: '28284459', found: '35804485'