萌新求助WA30
查看原帖
萌新求助WA30
511520
drmr楼主2024/6/6 15:38

link

#include <bits/stdc++.h>
#define DISABLE_MMAP
#pragma terget("avx,avx2,avx256f,sse2,sse3,sse4,sse4.2")
#define int unsigned long long
using namespace std;

const int N = 5e5;
int n, m, k, bit[N], a[N], from[N];
int deep[N], siz[N], bigson[N], fa[N], up[N], dfn[N], dfncnt;
vector<int> g[N];

struct point{
	int r0, r1, l0, l1;
	void make(int a, int b, int c, int d){
		r0 = a, r1 = b, l0 = c, l1 = d;
		return ;
	}
	point operator + (const point &b){
		point res;
		res.r0 = (~r0 & b.r0) | (r0 & b.r1);
		res.r1 = (~r1 & b.r0) | (r1 & b.r1);
		res.l0 = (~b.l0 & l0) | (b.l0 & l1);
		res.l1 = (~b.l1 & l0) | (b.l1 & l1);
		return res;
	}
}val[N];
vector<point> vecl, vecr;

void decomp(int u, int pre){
	deep[u] = deep[pre] + 1, siz[u] = 1; bigson[u] = 0, fa[u] = pre;
	for(int v : g[u]){
		if(v == pre) continue;
		decomp(v, u); siz[u] += siz[v];
		if(siz[v] > siz[bigson[u]]) bigson[u] = v;
	}
	return ;
}
void calup(int u, int pre, int val){
	dfn[u] = ++dfncnt, from[dfncnt] = u;
	up[u] = val; if(bigson[u]) calup(bigson[u], u, val);
	for(int v : g[u]){
		if(v == pre || v == bigson[u]) continue;
		calup(v, u, v);
	}
	return ;
}

void Build(int u, int l, int r){
	if(l == r){
		int all = (0ull - 1ull); l = from[l];
		if(bit[l] == 1) val[u].make(0 & a[l], all & a[l], 0 & a[l], all & a[l]);
		if(bit[l] == 2) val[u].make(0 | a[l], all | a[l], 0 | a[l], all | a[l]);
		if(bit[l] == 3) val[u].make(0 ^ a[l], all ^ a[l], 0 ^ a[l], all ^ a[l]);
		return ;
	}
	int mid = (l + r) >> 1ull;
	Build(2 * u, l, mid);
	Build(2 * u + 1, mid + 1, r);
	val[u] = val[2 * u] + val[2 * u + 1];
	return ;
}

void Modify(int u, int l, int r, int x){
	if(l == r){
		int all = (0ull - 1ull); l = from[l];
``		if(bit[l] == 2) val[u].make(0 | a[l], all | a[l], 0 | a[l], all | a[l]);
		if(bit[l] == 3) val[u].make(0 ^ a[l], all ^ a[l], 0 ^ a[l], all ^ a[l]);
		return ;
	}
	int mid = (l + r) >> 1ull;
	if(x <= mid) Modify(2 * u, l, mid, x);
	if(mid < x) Modify(2 * u + 1, mid + 1, r, x);
	val[u] = val[2 * u] + val[2 * u + 1];
	return ;
}

point Query(int u, int l, int r, int L, int R){
	if(L <= l && r <= R)
		return val[u];
	int mid = (l + r) >> 1ull;
	if(R <= mid) return Query(2 * u, l, mid, L, R);
	if(mid < L) return Query(2 * u + 1, mid + 1, r, L, R);
	return Query(2 * u, l, mid, L, R) + Query(2 * u + 1, mid + 1, r, L, R);
}

point lca(int x, int y){
	vecl.clear(), vecr.clear();
	// 先倍增往上跳喵,直接套板子喵
	while(up[x] != up[y]){
		if(deep[up[x]] <= deep[up[y]])
			vecr.push_back(Query(1, 1, n, dfn[up[y]], dfn[y])), y = fa[up[y]];
		else{
			point tmp = Query(1, 1, n, dfn[up[x]], dfn[x]);
			tmp.make(tmp.l0, tmp.l1, tmp.r0, tmp.r1);
			vecl.push_back(tmp), x = fa[up[x]];
		}
	}
	if(deep[x] <= deep[y]) vecr.push_back(Query(1, 1, n, dfn[x], dfn[y]));
	if(deep[x] > deep[y]){
		point tmp = Query(1, 1, n, dfn[y], dfn[x]);
		tmp.make(tmp.l0, tmp.l1, tmp.r0, tmp.r1);
		vecl.push_back(tmp);
	}
	point res;
	if(!vecl.empty() && vecr.empty()){
		res = vecl[0];
		if(vecl.size() >= 2)
			for(long long i = 1; i < vecl.size(); i++) res = res + vecl[i];
		return res;
	}
	else if(vecl.empty() && !vecr.empty()){
		res = vecr[vecr.size() - 1];
		if(vecr.size() >= 2)
			for(long long i = vecr.size() - 2; i >= 0; i--) res = res + vecr[i];
		return res;
	}
	res = vecl[0];
	if(vecl.size() >= 2)
		for(long long i = 1; i < vecl.size(); i++) res = res + vecl[i];
	if(vecr.size() >= 2)
		for(long long i = vecr.size() - 2; i >= 0; i--) res = res + vecr[i];
	return res;
}

signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin >> n >> m >> k;
	for(long long i = 1; i <= n; i++) cin >> bit[i] >> a[i];
	for(long long i = 1; i < n; i++){
		int x, y; cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	decomp(1, 0);
	calup(1, 0, 1);
	
	Build(1, 1, n);
	
	while(m--){
		int op, x, y, z;
		cin >> op >> x >> y >> z;
		if(op == 1){
			// 还要一个数位 DP 喵。
			int res = 0;
			point S = lca(x, y);
			int now0, now1;
			for(long long i = k - 1; i >= 0; i--){
				now0 = 1ull & (S.r0 >> i);
				now1 = 1ull & (S.r1 >> i);
				if(now0 >= now1 || (1ull << i) > z) res |= now0 * (1ull << i);
				else res |= now1 * (1ull << i), z -= (1ull << i);
			}
			cout << res << endl;
		}
		if(op == 2){
			bit[x] = y, a[x] = z;
			Modify(1, 1, n, dfn[x]);
		}
	}
	return 0;
}
2024/6/6 15:38
加载中...