• P3292 [SCOI2016]幸运数字 [线性基+倍增]


    线性基+倍增

    // by Isaunoya
    #include <bits/stdc++.h>
    using namespace std;
    
    #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
    #define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
    using ll = long long ;
    
    const int _ = 1 << 21;
    struct I {
    	char fin[_], *p1 = fin, *p2 = fin;
    	inline char gc() {
    		return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
    	}
    	inline I& operator>>(int& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c & 15);
    		while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    		x = sign ? x : -x;
    		return *this;
    	}
    	inline I& operator>>(ll& x) {
    		bool sign = 1;
    		char c = 0;
    		while (c < 48) ((c = gc()) == 45) && (sign = 0);
    		x = (c & 15);
    		while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
    		x = sign ? x : -x;
    		return *this;
    	}
    } in;
    struct O {
    	char st[100], fout[_];
    	signed stk = 0, top = 0;
    	inline void flush() {
    		fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
    	}
    	inline O& operator<<(ll x) {
    		if (top > (1 << 20)) flush();
    		if (x < 0) fout[top++] = 45, x = -x;
    		do
    			st[++stk] = x % 10 ^ 48, x /= 10;
    		while (x);
    		while (stk) fout[top++] = st[stk--];
    		return *this;
    	}
    	inline O& operator<<(char x) {
    		fout[top++] = x;
    		return *this;
    	}
    	inline O& operator<<(string s) {
    		if (top > (1 << 20)) flush();
    		for (char x : s) fout[top++] = x;
    		return *this;
    	}
    } out;
    #define pb emplace_back
    #define fir first
    #define sec second
    
    template < class T > inline void cmax(T & x , const T & y) {
    	(x < y) && (x = y) ;
    }
    template < class T > inline void cmin(T & x , const T & y) {
    	(x > y) && (x = y) ;
    }
    
    int n , q ;
    const int N = 2e4 + 10 ;
    ll g[N] , d[N][22][65] ;
    void ins(ll x , ll * p) {
    	for(int i = 63 ; ~ i ; i --)
    		if(x & (1ll << i)) {
    			if(! p[i]) p[i] = x ;
    			x ^= p[i] ;
    		}
    }
    void mergeto(ll * a , ll * b) { for(int i = 63 ; ~ i ; i --) if(a[i]) ins(a[i] , b) ;  }
    struct edge {int v , nxt ;} ; edge e[N << 1] ;
    int cnt = 0 , head[N] ;
    void add(int u , int v) { e[++ cnt] = { v , head[u] } ; head[u] = cnt ; }
    int fa[N] , dep[N] , f[N][22] ;
    void dfs(int u) {
    	for(int i = head[u] ; i ; i = e[i].nxt) {
    		int v = e[i].v ;
    		if(v ^ fa[u]) { fa[v] = u ; dep[v] = dep[u] + 1 ; dfs(v) ; }
    	}
    }
    ll ans[65] ;
    inline int Lca(int x , int y) {
    	if(dep[x] < dep[y]) swap(x , y) ;
    	for(int i = 20 ; ~ i ; i --) if(dep[f[x][i]] >= dep[y]) x = f[x][i] ;
    	if(x == y) return x ;
    	for(int i = 20 ; ~ i ; i --) if(f[x][i] ^ f[y][i]) { x = f[x][i] ; y = f[y][i] ; }
    	return f[x][0] ;
    }
    inline int getdis(int lca , int y) { return dep[y] - dep[lca] + 1 ; }
    inline ll query(int x , int y) {
    	memset(ans , 0 , sizeof(ans)) ;
    	int lca = Lca(x , y) , dis = getdis(lca , x) ;
    	for(int i = 20 ; ~ i ; i --) if(dis & (1 << i)) mergeto(d[x][i] , ans) , x = f[x][i] ;
    	dis = getdis(lca , y) ;
    	for(int i = 20 ; ~ i ; i --) if(dis & (1 << i)) mergeto(d[y][i] , ans) , y = f[y][i] ;
    	ll res = 0 ; for(int i = 63 ; ~ i ; i --) cmax(res , res ^ ans[i]) ;
    	return res ;
    }
    signed main() {
    #ifdef _WIN64
    	freopen("testdata.in" , "r" , stdin) ;
    #endif
    	in >> n >> q ;
    	rep(i , 1 , n) { in >> g[i] ; }
    	rep(i , 1 , n - 1) { int u , v ; in >> u >> v ; add(u , v) ; add(v , u) ; }
    	dfs(1) ; rep(i , 1 , n) f[i][0] = fa[i] ; rep(i , 1 , n) ins(g[i] , d[i][0]) ;
    	rep(j , 1 , 20) 
    		rep(i , 1 , n) { f[i][j] = f[f[i][j - 1]][j - 1] ; mergeto(d[i][j - 1] , d[i][j]) ; mergeto(d[f[i][j - 1]][j - 1] , d[i][j]) ; }
    	while(q --) { int u , v ; in >> u >> v ; out << query(u , v) << '
    ' ; }
    	return out.flush(), 0;
    }
    
  • 相关阅读:
    MySQL练习题
    MySql基础操作
    解决使用IDEA启动Tomcat成功但localhost:8080无法访问的问题
    1417. 重新格式化字符串--来源:力扣(LeetCode)
    字符消除
    Comsol中Absolute Pressure的解释
    气体流量与质量流率换算
    FileZilla MLSD错误:连接超时、读取目录列表失败
    Avalon总线的地址对齐与NIOS编程
    同步复位和异步复位--好文章就是要记录下来
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12189196.html
Copyright © 2020-2023  润新知