ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P3292 [SCOI2016]幸运数字

2020-07-07 22:05:28  阅读:263  来源: 互联网

标签:dep temp int ll P3292 read SCOI2016 幸运 include


lca倍增的途中,merge一下线性基。注意线性基是从自己开始,而倍增数组fa[i][0]等于father,意味着,线性基倍增的区间是左闭右开的,fa数组是左闭右闭

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<bitset>
#include<map>
//#include<regex>
#include<cstdio>
#include <iomanip>
#pragma GCC optimize(2)
#define up(i,a,b)  for(ll i=a;i<b;i++)
#define dw(i,a,b)  for(ll i=a;i>b;i--)
#define upd(i,a,b) for(ll i=a;i<=b;i++)
#define dwd(i,a,b) for(ll i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 20010;
struct node {
	int next, to;
}edge[N*2];
int head[N];
int cnt = 0;
void addedge(int u, int v)
{
	edge[cnt].next = head[u];
	edge[cnt].to = v;
	head[u] = cnt++;
}
ll val[N];
int n, q;
int dep[N];
int f[N][30];
struct xxj {
	ll b[65];
	xxj() {
		upd(i, 0, 60)b[i] = 0;
	}
	void insert(ll x)
	{
		dwd(i, 60, 0)
		{
			if (x >> i & 1ll)
			{
				if (b[i])
				{
					x ^= b[i];
				}
				else {
					b[i] = x;
					upd(j, 0, i - 1)if (b[i] >> j & 1ll)b[i] ^= b[j];
					upd(j, i + 1, 60)if (b[j] >> i & 1ll)b[j] ^= b[i];
					break;
				}
			}
		}
	}
}X[N][21];
void merge(xxj &t1, xxj t2)
{
	dwd(i, 60, 0)
	{
		if (t2.b[i] == 0)continue;
		t1.insert(t2.b[i]);
	}
}
void dfs(int u, int fa)
{
	dep[u] = dep[fa] + 1;
	f[u][0] = fa;
	X[u][0].insert(val[u]);
	upd(i, 1, 20)
	{
		if (f[u][i - 1] == 0)break;
		f[u][i] = f[f[u][i - 1]][i - 1];
		merge(X[u][i], X[f[u][i - 1]][i - 1]);
		merge(X[u][i], X[u][i - 1]);
	}
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (v == fa)continue;
		dfs(v, u);
	}
}
xxj lca(int x, int y)
{
	if (dep[x] < dep[y])swap(x, y);	
	xxj temp;
	if (dep[x] != dep[y])
	{
		dwd(i, 20, 0)
		{
			if (dep[f[x][i]] < dep[y])continue;
			merge(temp, X[x][i]);
			x = f[x][i];
		}
	}
	if (x == y)
	{
		temp.insert(val[x]);
		return temp;
	}
	dwd(i, 20, 0)
	{
		if (f[x][i] != f[y][i])
		{
			merge(temp, X[x][i]);
			merge(temp, X[y][i]);
			x = f[x][i]; y = f[y][i];
		}
	}
	temp.insert(val[f[x][0]]);
	temp.insert(val[x]);
	temp.insert(val[y]);
	return temp;
}
int main()
{
	n = read(), q = read();
	memset(head, -1, sizeof(head));
	upd(i, 1, n)val[i] = read();
	ll u, v;
	upd(i, 1, n - 1)
	{
		u = read(), v = read();
		addedge(u, v); addedge(v, u);
	}
	dfs(1, 0);
	while (q--)
	{
		u = read(), v = read();
		xxj res = lca(u, v);
		ll ans = 0;
		dwd(i, 60, 0)
		{
			ans ^= res.b[i];
		}
		printf("%lld\n", ans);
	}
	return 0;
}

标签:dep,temp,int,ll,P3292,read,SCOI2016,幸运,include
来源: https://www.cnblogs.com/LORDXX/p/13263556.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有