首页 > 其他分享 >CodeForces 1902F Trees and XOR Queries Again

CodeForces 1902F Trees and XOR Queries Again

时间:2023-12-10 12:22:06浏览次数:29  
标签:Again typedef XOR log int top 1902F long define

洛谷传送门

CF 传送门

如果我们能把 \(x \to y\) 路径上的所有点权插入到线性基,那么可以 \(O(\log V)\) 查询。

但是因为线性基合并只能 \(O(\log^2 V)\)(把一个线性基的所有元素插入到另一个),所以只能倍增做 \(O((n + q) \log n \log^2 V)\),过不了。

考虑 \(O(n \log V)\) 预处理出每个点到根的所有点权的线性基 \(f_u\),那么对于一个询问,把 \(f_x\) 和 \(f_y\) 合并,再抠掉 \(\text{lca}(x, y)\) 以上部分的点权即可。

但是线性基不支持删除,考虑贪心地在不影响线性基能组成的数的前提下,每个 \(f_u\) 中保留深度最大的点的点权(就是 CF1100F Ivan and Burgers 第一篇题解)。查询只考虑深度 \(\ge dep_{\text{lca}(x, y)}\) 的元素即可。

于是时间复杂度降至 \(O((n + q \log V) \log V)\)(瓶颈在合并线性基),可过。

code
// Problem: F. Trees and XOR Queries Again
// Contest: Codeforces - Educational Codeforces Round 159 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1902/problem/F
// Memory Limit: 512 MB
// Time Limit: 6500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
inline int read() {
    char c = getchar();
    int x = 0;
    for (; !isdigit(c); c = getchar()) ;
    for (; isdigit(c); c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x;
}

const int maxn = 200100;
const int logn = 20;

int n, m, a[maxn];
vector<int> G[maxn];

struct Basis {
	int p[20], q[20];
	
	inline void insert(int x, int y) {
		for (int i = 19; ~i; --i) {
			if (x & (1 << i)) {
				if (!p[i]) {
					p[i] = x;
					q[i] = y;
					break;
				} else if (q[i] < y) {
					swap(p[i], x);
					swap(q[i], y);
				}
				x ^= p[i];
			}
		}
	}
	
	inline bool check(int x, int y) {
		for (int i = 19; ~i; --i) {
			if ((x & (1 << i)) && y <= q[i]) {
				x ^= p[i];
			}
		}
		return !x;
	}
} g[maxn];

inline Basis operator + (const Basis &a, const Basis &b) {
	Basis res = a;
	for (int i = 0; i < 20; ++i) {
		if (b.p[i]) {
			res.insert(b.p[i], b.q[i]);
		}
	}
	return res;
}

int fa[maxn], sz[maxn], son[maxn], dep[maxn], top[maxn];

int dfs(int u, int f, int d) {
	fa[u] = f;
	sz[u] = 1;
	dep[u] = d;
	g[u] = g[f];
	g[u].insert(a[u], dep[u]);
	int mx = -1;
	for (int v : G[u]) {
		if (v == f) {
			continue;
		}
		sz[u] += dfs(v, u, d + 1);
		if (sz[v] > mx) {
			son[u] = v;
			mx = sz[v];
		}
	}
	return sz[u];
}

void dfs2(int u, int tp) {
	top[u] = tp;
	if (!son[u]) {
		return;
	}
	dfs2(son[u], tp);
	for (int v : G[u]) {
		if (!top[v]) {
			dfs2(v, v);
		}
	}
}

inline int qlca(int x, int y) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]]) {
			swap(x, y);
		}
		x = fa[top[x]];
	}
	if (dep[x] > dep[y]) {
		swap(x, y);
	}
	return x;
}

void solve() {
	n = read();
	for (int i = 1; i <= n; ++i) {
		a[i] = read();
	}
	for (int i = 1, u, v; i < n; ++i) {
		u = read();
		v = read();
		G[u].pb(v);
		G[v].pb(u);
	}
	dfs(1, 0, 1);
	dfs2(1, 1);
	m = read();
	while (m--) {
		int x, y, z;
		x = read();
		y = read();
		z = read();
		int lca = qlca(x, y);
		Basis b = g[x] + g[y];
		puts(b.check(z, dep[lca]) ? "YES" : "NO");
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:Again,typedef,XOR,log,int,top,1902F,long,define
From: https://www.cnblogs.com/zltzlt-blog/p/17892379.html

相关文章

  • 【题解】CodeForces 1902F Trees and XOR Queries Again
    传送门:https://codeforces.com/contest/1902/problem/F数据结构题,这里讲两种思路。$ST$表思路:判定“从若干个数中能否取出其中一些,使得异或和为$x$”的问题,第一时间想到线性基,本题要做的显然就是快速求出询问路径上所有数的线性基。两组数的线性基可以合并,方法为“暴力将......
  • F. Trees and XOR Queries Again
    首先容易想到lca+线性基,\(O(nlognB^2+qlognB^2)\),显然T飞了。#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<map>#include<vector>#include<set>#include<iostream>#include<queue>#i......
  • 汇编-xor异或
     XOR指令在两个操作数的对应位之间进行(按位)逻辑异或(XOR)操作,并将结果存在目标操作数中两个操作数的每一对对应位都应用如下操作原则:如果两个位值相同(同为0或同为1),则结果位等于0;否则结果位等于1。下标描述的是布尔运算x⊕y: 与0异或值不变,与1异或则被触发(求补)。对相同操作数进......
  • [AGC052B] Tree Edges XOR 题解
    题目链接点击打开链接题目解法怎么感觉这场\(B\)比\(C\)思维量更大考虑一步很妙的操作:把边权变成点权,以达到简化操作的目的使每条边的边权为两端点的异或和,手画一下可以发现,操作简化成了交换两端点的点权我们定义\(d_{1/2,i}\)定义为在\(1/2\)树上,\(i\)到根的权值......
  • D2. Xor-Subsequence (hard version)
    D2.Xor-Subsequence(hardversion)Itisthehardversionoftheproblem.Theonlydifferenceisthatinthisversion$a_i\le10^9$.Youaregivenanarrayof$n$integers$a_0,a_1,a_2,\ldotsa_{n-1}$.Bryapwantstofindthelongestbeautifulsub......
  • 简单的文件加密程序(md5xor异或winlinux)
    简介小程序是基于md5+password+xor的组合方式来加密文件。程序支持跨平台(Windows/Linux)。使用方法: 源文件清单:main.c  md5.c  md5.h  setup.sh 完整代码(main.c):#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#i......
  • Linux openssh问题解决: Permission denied, please try again
    1.vim打开sshd_config文件vim/etc/ssh/sshd_config2.搜索PermitRootLogin ,将 PermitRootLoginprohibie-password 改为如下:PermitRootLoginyes  ......
  • 修复Xorg服务文档(包含如何检测是否正常)
    //20231114editbypanwanli写在前面:最近Xorg服务老是出问题,重启、重装都不起作用,最终更改nvidia-xconfig命令参数解决;在此记录一下解决办法现象Xorg服务起不来,报错提示找不到屏幕或者无法分配none屏幕nvidia-smi命令查看不到Xorg进程尝试过的办法重启Xorg:有的......
  • xor 线性基
    voidadd(intx){ dn(i,60,0)if(x>>i&1){ if(mg[i])x=x^mg[i]; else{mg[i]=x;break;} }}线性基的第\(i\)位如果有数,那它最高位是\(2^i\)。首先这样搞出来的是一个线性基,它有这些性质(线性基能相互异或得到原集合的所有相互异或得到的值。线性基是满足上......
  • cf1325D. Ehab the Xorcist(位运算trick)
    https://codeforces.com/contest/1325/problem/D有一个非常经典的结论a+b=(a^b)+2(a&b)这个题就可以往上面靠,首先我们观察一下,对于两个数的情况,如果(v-u)mod2=1,必然无解,试着将它扩展一下,也是对的,因为最低一位没有进位。可以确定的是ans<=3仿照上面的式子,令a=u,b=c=((a+b......