• F


    F - Encounter and Farewell

    观摩自大佬博客 https://blog.csdn.net/qq_42101694/article/details/116349687

    只写关于其中一些不懂的解释

    关于这个a-b的路径为何能用补集中的数异或出来呢。

    假设有三条边,联通的。a - b - c ,那么a ^ c=a ^ b ^ b ^ c,其中a ^ b,b ^ c分别是边权。也就是a ^ c等于路径异或值,也就是可以被补集中的一些数字异或得到。

    充要条件为什么会是这个呢。我们可以把构造出的一个树看出以0为根节点的树,0 ^ i = i ,所以被异或出来的和要有所有的0-i这个路径,必须要有全部的。

    然后怎么构造,直接用并查集暴力就行了,线性基里面最多只有18个。

    #pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
    #pragma GCC optimize(3 , "Ofast" , "inline")
    #pragma GCC optimize("Ofast")
    #pragma GCC target("avx,avx2,fma")
    #pragma GCC optimization("unroll-loops")
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <unordered_map>
    #include <vector>
    #include <map>
    #include <list>
    #include <queue>
    #include <cstring>
    #include <cstdlib>
    #include <ctime>
    #include <cmath>
    #include <stack>
    #include <set>
    #include <bitset>
    #include <deque>
    using namespace std ;
    #define ios ios::sync_with_stdio(false) , cin.tie(0)
    #define x first
    #define y second
    #define pb push_back
    #define ls rt << 1
    #define rs rt << 1 | 1
    typedef long long ll ;
    const double esp = 1e-6 , pi = acos(-1) ;
    typedef pair<int , int> PII ;
    const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
    int n , a[N] , b[N] , id[N] , fa[N] ;
    int find(int x) {
    	return fa[x] == x ? x : fa[x] = find(fa[x]) ;
    }
    int nn , m ;
    int work()
    {
      cin >> nn >> m ;
      for(int i = 0 ;i <= 18 ;i ++ ) 
      	 if(nn >> i & 1) n = i ;
      for(int i = 0 , x ; i < m ;i ++ ) cin >> x , a[x] = 1 ;
      for(int i = 1 ;i < nn ;i ++ ) {
      	if(!a[i]) {
      		int x = i ;
      		for(int j = n ;j >= 0 ;j -- ) {
      			if(x >> j & 1) {
      				if(b[j]) x ^= b[j] ;
      				else {
      					b[j] = x ;
      					id[j] = i ;
      					break ;
      				}
      			}
      		}
      	}
      }
      for(int i = 0 ;i < n ;i ++ ) 
      	 if(!id[i]) return 0 * puts("-1") ; 
      for(int i = 0 ;i < nn ;i ++ ) fa[i] = i ;
      for(int i = 0 ;i < nn ;i ++ )  
      	 for(int j = 0 ;j < n ;j ++ ) {
      	 	int fu = find(i) , fv = find(i ^ id[j]) ;
      	 	if(fu != fv) {
      	 		cout << i << " " << (i ^ id[j]) << "
    " ;
      	 		fa[fu] = fv ;
      	 	}
      	 }
    
      return 0 ;
    }
    int main()
    {
      //   freopen("C://Users//spnooyseed//Desktop//in.txt" , "r" , stdin) ;
      //   freopen("C://Users//spnooyseed//Desktop//out.txt" , "w" , stdout) ;
    
      work() ;
      return 0 ;
    }
    /*
    
    */
    
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    HDU 3874 Necklace 区间查询的离线操作
    POJ 1651 Multiplication Puzzle (区间dp)
    POJ 2528 Mayor's posters(离散+线段树)
    POJ 2886 Who Gets the Most Candies?
    webgl教程
    GL_ARRAY_BUFFER 和 GL_ELEMENT_ARRAY_BUFFER
    几个不错的webgl教程网
    svg图标库
    sublime text nodejs set
    图形学着色器学习
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/14819407.html
Copyright © 2020-2023  润新知