zoukankan      html  css  js  c++  java
  • Codeforces 1218D Xor Spanning Tree FWT

    根据题目描述可知是个特殊的仙人掌, 然后把环扣出来fwt算方案数就好了。

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mk make_pair
    #define PII pair<int, int>
    using namespace std;
    
    const int N = 1 << 17;
    const int mod = (int)1e9 + 7;
    const int mod2 = 998244353;
    
    int n, m, xr, fa[N], fa_w[N];
    int dfn[N], dfs_clock;
    vector<PII> G[N];
    vector<vector<int>> VV;
    
    int a[N], b[N], c[N], d[N];
    
    void dfs(int u, int pa) {
        dfn[u] = ++dfs_clock;
        for(auto &e : G[u]) {
            int v = e.se, w = e.fi;
            if(v == pa) continue;
            if(!dfn[v]) {
                fa[v] = u, fa_w[v] = w;
                dfs(v, u);
            }
            else if(dfn[v] > dfn[u]) {
                vector<int> V;
                int cur_xr = w;
                for(int cur = v; cur != u; cur = fa[cur]) {
                    cur_xr ^= fa_w[cur];
                }
                V.push_back(cur_xr ^ w);
                for(int cur = v; cur != u; cur = fa[cur]) {
                    V.push_back(cur_xr ^ fa_w[cur]);
                }
                xr ^= cur_xr;
                VV.push_back(V);
            }
        }
    }
    
    void fwt_xor(int *a, int n, int dft, int mod, int inv2) {
        for(int i = 1; i < n; i <<= 1) {
            for(int j = 0; j < n; j += i << 1) {
                for(int k = j; k < j + i; k++) {
                    int x = a[k], y = a[i + k];
                    a[k] = (x + y) % mod; a[i + k] = (x - y + mod) % mod;
                    if(dft == -1) a[k] = 1LL * a[k] * inv2 % mod, a[i + k] = 1LL * a[i + k] * inv2 % mod;
                }
            }
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            G[u].push_back(mk(w, v));
            G[v].push_back(mk(w, u));
            xr ^= w;
        }
        dfs(1, 0);
        a[xr] = 1;
        c[xr] = 1;
        fwt_xor(a, 1 << 17, 1, mod, (mod + 1) >> 1);
        fwt_xor(c, 1 << 17, 1, mod2, (mod2 + 1) >> 1);
        for(auto &V : VV) {
            memset(b, 0, sizeof(b));
            memset(d, 0, sizeof(c));
            for(auto &t : V) b[t]++, d[t]++;
            fwt_xor(b, 1 << 17, 1, mod, (mod + 1) >> 1);
            fwt_xor(d, 1 << 17, 1, mod2, (mod2 + 1) >> 1);
            for(int i = 0; i < (1 << 17); i++) {
                a[i] = 1LL * a[i] * b[i] % mod;
                c[i] = 1LL * c[i] * d[i] % mod2;
            }
        }
        fwt_xor(a, 1 << 17, -1, mod, (mod + 1) >> 1);
        fwt_xor(c, 1 << 17, -1, mod2, (mod2 + 1) >> 1);
        for(int i = 0; i < (1 << 17); i++) {
            if(a[i] || c[i]) {
                printf("%d %d
    ", i, a[i]);
                return 0;
            }
        }
        return 0;
    }
    
    /**
    **/
  • 相关阅读:
    5. Longest Palindromic Substring
    24. Swap Nodes in Pairs
    23. Merge k Sorted Lists
    22. Generate Parentheses
    21. Merge Two Sorted Lists
    20. Valid Parentheses
    19. Remove Nth Node From End of List
    18. 4Sum
    17. Letter Combinations of a Phone Number
    14. Longest Common Prefix
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11719574.html
Copyright © 2011-2022 走看看