zoukankan      html  css  js  c++  java
  • Luogu 4151 [WC2011]最大XOR和路径

    你谷又乱评分……

    首先发现答案只有可能是从$1$开始走到$n$,中间绕若干个环,然后使它取到的异或值最大。

    这样子的话我们可以随便先取一条路径,强制选择走这条路径,然后把所有的环都丢进线性基里面去,因为如果要选择一个环,我们从路径中的一个点走出去然后在这个环上绕几圈然后走回来,发现中间这个“走出去”,“走回来”的过程中的点被异或了两遍,相当于不产生贡献。

    其实就是搜一遍的事情。

    时间复杂度$O(nlogn)$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 5e4 + 5;
    const int M = 2e5 + 5;
    
    int n, m, tot = 0, head[N];
    ll dis[N];
    bool vis[N];
    
    struct Edge {
        int to, nxt;
        ll val;
    } e[M];
    
    inline void add(int from, int to, ll val) {
        e[++tot].to = to;
        e[tot].val = val;
        e[tot].nxt = head[from];
        head[from] = tot;
    }
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMax(ll &x, ll y) {
        if(y > x) x = y;
    }
    
    namespace Lp {
        ll p[70];
        
        inline void ins(ll val) {
            for(int i = 63; i >= 0; i--) {
                if((val >> i) & 1) {
                    if(!p[i]) {
                        p[i] = val;
                        break;
                    }
                    val ^= p[i];
                }
            }
        }
        
        inline ll query(ll res) {
            for(int i = 63; i >= 0; i--) 
                chkMax(res, (res ^ p[i]));
            return res;
        }
        
    } using namespace Lp;
    
    void dfs(int x) {
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(!vis[y]) {
                vis[y] = 1;
                dis[y] = dis[x] ^ e[i].val;
                dfs(y);
            } else ins(dis[x] ^ dis[y] ^ e[i].val);
        }
    }
    
    int main() {
        read(n), read(m);
        for(int x, y, i = 1; i <= m; i++) {
            read(x), read(y);
            ll v; read(v);
            add(x, y, v), add(y, x, v);
        }
        
        dfs(1);
        
        printf("%lld
    ", query(dis[n]));
        return 0;
    }
    View Code
  • 相关阅读:
    372. Super Pow
    桌面远程连接:发生身份验证错误,要求的函数不受支持
    Web Service代理类生成工具
    Razor语法大全
    Web Serveice服务代理类生成及编译
    配置WCF Test Client
    我与春风皆过客,你携秋水揽星河
    机器学习(十三) 集成学习和随机森林(下)
    机器学习(十三) 集成学习和随机森林(上)
    机器学习(十二) 决策树(下)
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9695553.html
Copyright © 2011-2022 走看看