Bzoj2115: [Wc2011] Xor

题面

传送门

Sol

线性基辣
肯定是一条路径然后上面走了若干个环的形式
把每个环丢到线性基里去
询问任意一条\(1\)\(n\)的异或和求解

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
# define Copy(a, b) memcpy(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(5e4 + 5);
const int __(1e5 + 5);
 
IL ll Input(){
    RG char c = getchar(); RG ll x = 0, z = 1;
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}
 
int n, m, cnt, first[_], vis[_];
ll dis[_], pw[63] = {1};
struct Bac{
    ll b[63];
 
    IL void Insert(RG ll x){
        for(RG int i = 62; ~i; --i){
            if(~x & pw[i]) continue;
            if(!b[i]){
                b[i] = x;
                break;
            }
            x ^= b[i];
        }
    }
 
    IL ll Calc(RG ll x){
        for(RG int i = 62; ~i; --i) x = max(x, x ^ b[i]);
        return x;
    }
} B;
struct Edge{
    int to, next;
    ll w;
} edge[__ << 1];
 
IL void Add(RG int u, RG int v, RG ll w){
    edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;
}
 
IL void Dfs(RG int u){
    vis[u] = 1;
    for(RG int e = first[u]; e != -1; e = edge[e].next){
        RG int v = edge[e].to; RG ll w = edge[e].w;
        if(vis[v]) B.Insert(dis[v] ^ dis[u] ^ w);
        else dis[v] ^= dis[u] ^ w, Dfs(v);
    }
}
 
int main(RG int argc, RG char* argv[]){
    n = Input(), m = Input(), Fill(first, -1);
    for(RG int i = 1; i < 63; ++i) pw[i] = pw[i - 1] << 1;
    for(RG int i = 1; i <= m; ++i){
        RG int u = Input(), v = Input(); RG ll w = Input();
        Add(u, v, w), Add(v, u, w);
    }
    Dfs(1);
    printf("%lld\n", B.Calc(dis[n]));
    return 0;
}
posted @ 2018-03-16 21:56  Cyhlnj  阅读(120)  评论(0编辑  收藏  举报