zoukankan      html  css  js  c++  java
  • Solution -「Gym 102956F」Find the XOR

    (mathcal{Description})

      Link.

      给定 (n) 个点 (m) 条边的连通无向图 (G),边有边权。其中 (u,v) 的距离 (d(u,v)) 定义为 (u)(v) 的最大异或路径。还有 (q) 次询问,每次给出 (l,r),求 (igoplus_{lle i<jle r}d(i,j))

      (n,m,qle10^5),边权 (w<2^{30})

    (mathcal{Solution})

      首先必然套用这个经典永流传的结论:设所有环的异或和构成空间 (V)(d'(u,v))(u)(v) 的任意一条路径的异或和,则 (d(u,v)=max{d'(u,v)oplus xmid xin V})

      记变换 (F_V:x ightarrow max{xoplus vmid vin V}),由于它不具有线性性,我们拆开 (d(u,v))(max) 进行优化就显得困难。不过,考查与之类似的另一个变换 (G_V:x ightarrowmin{xoplus vmid vin V}),能够证明 (G_V) 是线性变换,且会得到一个炫酷的结论:(F_V(x)=G_V(x)oplusmax{vmid vin V})

    证明   把 $x$ 等元素视为 $U={0,1}^k$ 下的向量。设 $oldsymbol x=egin{pmatrix}x_0& x_1&cdots& x_{k-1}end{pmatrix}$,取 $U$ 的子空间 $V$ 的线性基 $mathcal B$,令 $$ mathcal B=egin{pmatrix}oldsymbol b_0\ oldsymbol b_1\ vdots \ oldsymbol b_{k-1}end{pmatrix}, $$ 其中 $oldsymbol b_i=egin{pmatrix} b_{i,0} & b_{i,1}&cdots& b_{i,k-1} end{pmatrix}$,且有 $forall jlt i,b_{i,j}=0$。此时考虑 $oldsymbol xmathcal B^T$ 的意义:若 $oldsymbol x$ 某一分量为 $1$,则加上(即异或上)线性基中的对应向量,很显然就是在线性基中构造 $min{xoplus vmid vin V}$ 的方式,所以 $G_V$ 是一个线性变换。 $square$

      “炫酷结论”就不证了,自证不难。

      回到题目,处理一下式子:

    [egin{aligned}igoplus_{lle i<jle r}d(i,j) &= igoplus_{lle i<jle r}d'(i,j)oplus G_V(d'(i,j))oplus max{vmid vin V}\&= left(inom{r-l+1}{2}otimesmax{vmid vin V} ight)oplus G_Vleft( igoplus_{lle i<jle r}d'(i,j) ight).end{aligned} ]

    抵消掉大量重复异或之后直接计算即可。复杂度 (mathcal O(n+(m+q)log w))

    (mathcal{Code})

    /*~Rainybunny*/
    
    #include <bits/stdc++.h>
    
    #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
    #define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
    
    const int MAXN = 1e5;
    int n, m, q, ecnt, head[MAXN + 5], dis[MAXN + 5];
    bool vis[MAXN + 5];
    
    struct Edge { int to, val, nxt; } graph[MAXN * 2 + 5];
    
    struct XorLinearBasic {
        static const int W = 30;
        int bas[W];
    
        inline void insert( int v ) {
            per ( i, W, 0 ) if ( v >> i & 1 ) {
                if ( !bas[i] ) return void( bas[i] = v );
                v ^= bas[i];
            }
        }
    
        inline int ask( int v, const bool tar ) {
            per ( i, W, 0 ) if ( ( v >> i & 1 ) != tar ) v ^= bas[i];
            return v;
        }
    } xlb;
    
    inline void link( const int u, const int v, const int w ) {
        graph[++ecnt] = { v, w, head[u] }, head[u] = ecnt;
        graph[++ecnt] = { u, w, head[v] }, head[v] = ecnt;
    }
    
    inline void getCir( const int u ) {
        vis[u] = true;
        for ( int i = head[u], v; i; i = graph[i].nxt ) {
            if ( vis[v = graph[i].to] ) {
                xlb.insert( dis[u] ^ dis[v] ^ graph[i].val );
            } else {
                dis[v] = dis[u] ^ graph[i].val, getCir( v );
            }
        }
    }
    
    int main() {
        std::ios::sync_with_stdio( false ), std::cin.tie( 0 );
    
        std::cin >> n >> m >> q;
        rep ( i, 1, m ) {
            int u, v, w; std::cin >> u >> v >> w;
            link( u, v, w );
        }
    
        getCir( 1 );
        rep ( i, 1, n ) dis[i] ^= dis[i - 1];
    
        for ( int l, r; q--; ) {
            std::cin >> l >> r;
            std::cout << xlb.ask( ( r - l ) & 1 ? dis[r] ^ dis[l - 1] : 0,
              ( r - l + 1ll ) * ( r - l ) >> 1 & 1 ) << '
    ';
        }
        return 0;
    }
    
    
  • 相关阅读:
    BootStrap Table前台和后台分页对JSON格式的要求
    神奇的外部嵌套(使用ROW_NUMBER()查询带条件的时候提示列名无效)
    要想获取select的值,使用ng-modle,否则无法获取select 的值
    Angular使用操作事件指令ng-click传多个参数示例
    Jenins 邮件通知
    Jenkins 流水线(Pipeline)
    Jenkins Master-Slave 架构
    Jenins 参数化构建
    Jenkins 用户权限管理
    Jenkins 安装
  • 原文地址:https://www.cnblogs.com/rainybunny/p/15190274.html
Copyright © 2011-2022 走看看