首页 > 其他分享 >洛谷 P3292 [SCOI2016]幸运数字

洛谷 P3292 [SCOI2016]幸运数字

时间:2023-04-13 19:47:42浏览次数:68  
标签:box std 洛谷 fa int P3292 merge boxx SCOI2016

https://www.luogu.com.cn/problem/P3292

多次询问求一条链取若干点的最大异或和

考虑一个集合的最大异或和可以求出线性基完成,两个集合的线性基可以合并,但是线性基并没有可减性,于是我们求 lca 的时候只能每次往集合里添加一条链,为了保证复杂度只能用倍增做。

std::vector<i64> merge(std::vector<i64> a, std::vector<i64> b) {
	std::vector<i64> c = a;
	for (int i = 60; i >= 0; i--) {
		i64 t = b[i];
		for (int j = 60; j >= 0; j--) {
			if (!t) break; if ((t >> j & 1) == 0) continue;
			if (!c[j]) c[j] = t; t ^= c[j];
		}
	}
	return c;
}

int main() {
	int n = read(), Q = read(); i64 val[n + 1];
	std::vector<int> edge[n + 1];
	for (int i = 1; i <= n; i++) val[i] = read();
	edge[1].push_back(0);
	for (int i = 1; i < n; i++) {
		int u = read(), v = read();
		edge[u].push_back(v); edge[v].push_back(u);
	}
	int fa[n + 1][20] = {0}, dep[n + 1] = {0};
	std::vector<i64> box[n + 1][20];
	std::function<void(int, int)> dfs = [&](int u, int last) -> void {
		dep[u] = dep[last] + 1;
		for (auto v : edge[u]) {
			if (v == last) {
				fa[u][0] = v; box[u][0].resize(61);
				for (int j = 60; j >= 0; j--) {
					if ((val[u] >> j & 1) == 0) {box[u][0][j] = val[u]; break;}
				}
				for (int j = 1; j <= 18; j++) {
					int F = fa[u][j - 1];
					if (!F || !fa[F][j - 1]) break;
					fa[u][j] = fa[F][j - 1];
					box[u][j] = merge(box[u][j - 1], box[F][j - 1]);
				}
				break;
			}
		}
		for (auto v : edge[u]) {
			if (v == last) continue; dfs(v, u);
		}
	};
	dfs(1, 0);
	while (Q--) {
		std::vector<i64> boxx(61, 0);
		int x = read(), y = read();
		if (dep[x] < dep[y]) std::swap(x, y);
		int t = dep[x] - dep[y], p = 0;
		while (t) {
			if (t & 1) {
				boxx = merge(boxx, box[x][p]); x = fa[x][p];
			}
			t >>= 1; p++;
		}
		if (x != y) {
			for (int i = 18; i >= 0; i--) {
				if (fa[x][i] == fa[y][i]) continue;
				boxx = merge(boxx, box[x][i]);
				boxx = merge(boxx, box[y][i]);
				x = fa[x][i]; y = fa[y][i];
			}
			boxx = merge(boxx, box[x][0]);
			boxx = merge(boxx, box[y][0]);
			x = fa[x][0];
		}
		boxx = merge(boxx, box[x][0]);
		i64 ans = 0;
		for (int i = 60; i >= 0; i--) {
			ans = std::max(ans, ans ^ boxx[i]);
		}
		printf("%lld\n", ans);
	}
}

标签:box,std,洛谷,fa,int,P3292,merge,boxx,SCOI2016
From: https://www.cnblogs.com/zrzring/p/LGP3292.html

相关文章

  • w1 洛谷T233243
      主要思路就是计算每一个长度为2的子串出现的次数,计数的同时用数组记录次数,打擂台找到出现次数最多的子串,首字符出现的位置就是数组的下标。最后输出出现最多的子串。代码如下:#include<bits/stdc++.h>usingnamespacestd;intcnt[100];intmain(){ intn,max=-1; ......
  • 洛谷P2415 集合求和(数学问题,使用集合子集求和公式)
    可以知道对于一个有n个数据的集合,其子集个数有2^n个至于证明可以这样理解,对于n个数据,其子集就是对数据进行组和,而对于每个位置上的数据,组合时仅有两种状态即有此数据或无此数据,也就是有两种可能,而对于n个数据,就有2^n种可能不妨设其中一个非空数据X,对于X,依据X可以将子集划分为两......
  • 洛谷与 Codeforces 的难度评级
    为了比较CF与洛谷的题目难度评级,我写了一个爬虫,爬取了CF题目在源站和洛谷中的难度,并进行比较。这里先给出两者的换算:洛谷入门普及-普及/提高-普及+/提高提高+/省选-省选/NOI-NOI/NOI+/CTSCCF800900-11001200-15001600-19002000-23002400-29003000-350......
  • 洛谷P1308统计单词数,strtok函数的使用以及对于单词分割的一些思考
    [NOIP2011普及组]统计单词数题目描述一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。注意......
  • 洛谷P1552 [APIO2012] 派遣 题解 左偏树
    题目链接:https://www.luogu.com.cn/problem/P1552题目大意:每次求子树中薪水和不超过\(M\)的最大节点数。解题思路:使用左偏树维护一个大根堆。首先定义一个Node的结构体:structNode{ints[2],c,sz,dis;longlongsum;Node(){};Node(int_c){s......
  • 洛谷4113(树状数组+离线处理)
    [HEOI2012]采花题目描述萧薰儿是古国的公主,平时的一大爱好是采花。今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花。花园足够大,容纳了$n$朵花,共有$c$种颜色,用整数$1\simc$表示。且花是排成一排的,以便于公主采花。公主每次采花后会统计采到的花的颜色数,颜色......
  • 洛谷 P3377 【模板】左偏树(可并堆)题解 左偏树模板题
    题目链接:https://www.luogu.com.cn/problem/P3377维护左偏树的同时还需要维护一个并查集。但是并查集也就一个find操作。pop的时候更新f[x]的操作很神奇。示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1e5+5;intn,m,op,x,y,val[m......
  • 对未来的自己的一个提醒。关于打表答题的思路,洛谷P5731
    P5731【深基5.习6】蛇形方阵-洛谷|计算机科学教育新生态(luogu.com.cn)这道题就是纯纯找规律的模拟题,但是在比赛或者思维比较松散的情况下紧张的时候会想不出模拟思路这时候如果测试数据的范围比较小,如本题的数据最大就到九阶方阵,所以可以手算出每一种类型打表输出,不用去......
  • 洛谷 P2398. GCD SUM
    题目描述求$$\sum\limits_{i=1}^n\sum\limits_{j=1}^n\gcd(i,j)$$输入:2输出:5算法1 线性筛 $O(n)$将式子变形:要知道一个前置定理$\sum\limits_{d|n}\varphi(d)=n$艾弗森约定:定义$\\\[P]$=$$\begin{cases}P\text{}is\text{}tr......
  • 洛谷 P8918 『MdOI R5』Jump 题解
    题目传送门这一题其实很简单,只是要想到正确方法我一开始用了奇怪的搜索①无解的情况:看上去很离奇,实际上略加思索就会发现,如果输入\(n\)为偶数,那么就铁定无解。证明过程如下:令\(n\bmod{2}=0\),人距离\(n\)点的距离为\(dis\),则当走出第一步(步长为\(1\))时,有:\[dis=\midn......