BZOJ 3282 Tree Link-Cut-Tree 动态树

本文详细介绍了如何维护一种动态树形数据结构,包括求两点间点的异或和、连接两点、删除边及修改点权等操作。采用LCT(Lazy Propagation Tree)实现,适用于不保证连通性的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:维护一种动态树形数据结构,支持:

1.求树上两点之间的点的异或和。

2.连接两点(不保证不连通)

3.删除连点之间的边(不保证两点联通)

4.将一个点的点权改成一个值


思路:还是LCT,思路也比较裸。主要是它各种不保证,所以要多加判断。


CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 300010
using namespace std;

struct Complex{
	int val,_xor;
	bool reverse;
	Complex *son[2],*father;

	Complex(int _val);
	void Reverse() {
		reverse ^= 1;
		swap(son[0],son[1]);
	}
	bool Check() {
		return father->son[1] == this;
	}
	void PushDown();
	void PushUp();
}*tree[MAX],*nil = new Complex(0);
Complex:: Complex(int _val) {
	val = _xor = _val;
	reverse = false;
	son[0] = son[1] = father = nil;
}
void Complex:: PushDown() {
	if(reverse) {
		son[0]->Reverse();
		son[1]->Reverse();
		reverse = false;
	}
}
void Complex:: PushUp() {
	_xor = son[0]->_xor ^ son[1]->_xor ^ val;
}

int points,asks;
int src[MAX];

inline void Rotate(Complex *a,bool dir);
inline void Splay(Complex *a);
inline void PushPath(Complex *a);

inline void Access(Complex *a);
inline void ToRoot(Complex *a);
inline void Link(Complex *x,Complex *y);
inline void Cut(Complex *x,Complex *y);
inline void Modify(Complex *a,int c);
inline int Ask(Complex *x,Complex *y);

inline Complex *FindRoot(Complex *x);

int main()
{
	cin >> points >> asks;
	for(int x,i = 1;i <= points; ++i)
		scanf("%d",&x),tree[i] = new Complex(x);
	for(int flag,x,y,i = 1;i <= asks; ++i) {
		scanf("%d%d%d",&flag,&x,&y);
		if(!flag)	printf("%d\n",Ask(tree[x],tree[y]));
		else if(flag == 1)	Link(tree[x],tree[y]);
		else if(flag == 2)	Cut(tree[x],tree[y]);
		else	Modify(tree[x],y);
	}
	return 0;
}

inline void Rotate(Complex *a,bool dir)
{
	Complex *f = a->father;
	f->son[!dir] = a->son[dir];
	f->son[!dir]->father = f;
	a->son[dir] = f;
	a->father = f->father;
	if(f->father->son[0] == f || f->father->son[1] == f)
		f->father->son[f->Check()] = a;
	f->father = a;
	f->PushUp();
}

inline void Splay(Complex *a)
{
	PushPath(a);
	while(a == a->father->son[0] || a == a->father->son[1]) {
		Complex *p = a->father->father;
		if(p->son[0] != a->father && p->son[1] != a->father)
			Rotate(a,!a->Check());
		else if(!a->father->Check()) {
			if(!a->Check())
				Rotate(a->father,true),Rotate(a,true);
			else	Rotate(a,false),Rotate(a,true);
		}
		else {
			if(a->Check())
				Rotate(a->father,false),Rotate(a,false);
			else	Rotate(a,true),Rotate(a,false);
		}
	}	
	a->PushUp();
}

inline void PushPath(Complex *a)
{
	static Complex *stack[MAX];
	int top = 0;
	for(;a->father->son[0] == a || a->father->son[1] == a;a = a->father)
		stack[++top] = a;
	stack[++top] = a;
	while(top)
		stack[top--]->PushDown();
}

inline void Access(Complex *a)
{
	Complex *last = nil;
	while(a != nil) {
		Splay(a);
		a->son[1] = last;
		a->PushUp();
		last = a;
		a = a->father;
	}
}

inline void ToRoot(Complex *a)
{
	Access(a);
	Splay(a);
	a->Reverse();
}

inline void Link(Complex *x,Complex *y)
{
	if(FindRoot(x) == FindRoot(y))	return ;
	ToRoot(x);
	x->father = y;
}

inline void Cut(Complex *x,Complex *y)
{
	if(x == y || FindRoot(x) != FindRoot(y))	return ; 
	ToRoot(x);
	Access(y);
	Splay(y);
	if(y->son[0] != x)	return ;
	y->son[0] = nil;
	x->father = nil;
	y->PushUp();
}

inline Complex *FindRoot(Complex *a)
{
	while(a->father != nil)
		a = a->father;
	return a;
}

inline void Modify(Complex *a,int c)
{
	Splay(a);
	a->val = c;
	a->PushUp();
}

inline int Ask(Complex *x,Complex *y)
{
	ToRoot(x);
	Access(y);
	Splay(y);
	return y->_xor;
}


电动汽车数据集:2025年3K+记录 真实电动汽车数据:特斯拉、宝马、日产车型,含2025年电池规格和销售数据 关于数据集 电动汽车数据集 这个合成数据集包含许多品牌和年份的电动汽车和插电式车型的记录,捕捉技术规格、性能、定价、制造来源、销售和安全相关属性。每一行代表由vehicle_ID标识的唯一车辆列表。 关键特性 覆盖范围:全球制造商和车型组合,包括纯电动汽车和插电式混合动力汽车。 范围:电池化学成分、容量、续航里程、充电标准和速度、价格、产地、自主水平、排放、安全等级、销售和保修。 时间跨度:模型跨度多年(包括传统和即将推出的)。 数据质量说明: 某些行可能缺少某些字段(空白)。 几个分类字段包含不同的、特定于供应商的值(例如,Charging_Type、Battery_Type)。 各列中的单位混合在一起;注意kWh、km、hr、USD、g/km和额定值。 列 列类型描述示例 Vehicle_ID整数每个车辆记录的唯一标识符。1 制造商分类汽车品牌或OEM。特斯拉 型号类别特定型号名称/变体。型号Y 与记录关联的年份整数模型。2024 电池_类型分类使用的电池化学/技术。磷酸铁锂 Battery_Capacity_kWh浮充电池标称容量,单位为千瓦时。75.0 Range_km整数表示充满电后的行驶里程(公里)。505 充电类型主要充电接口或功能。CCS、NACS、CHAdeMO、DCFC、V2G、V2H、V2L Charge_Time_hr浮动充电的大致时间(小时),上下文因充电方法而异。7.5 价格_USD浮动参考车辆价格(美元).85000.00 颜色类别主要外观颜色或饰面。午夜黑 制造国_制造类别车辆制造/组装的国家。美国 Autonomous_Level浮点自动化能力级别(例如0-5),可能包括子级别的小
### 关于 BZOJ1728 Two-Headed Cows (双头牛) 的算法解析 此问题的核心在于如何通过有效的图论方法解决给定约束下的最大独立集问题。以下是详细的分析和解答。 #### 问题描述 题目要求在一个无向图中找到最大的一组节点集合,使得这些节点之间满足特定的颜色匹配条件。具体来说,每条边连接两个节点,并附带一种颜色标记(A 或 B)。对于任意一条边 \(u-v\) 和其对应的颜色 \(c\),如果这条边属于最终选取的子集中,则必须有至少一个端点未被选入该子集或者两端点均符合指定颜色关系。 #### 解决方案概述 本题可以通过 **二分枚举 + 图染色验证** 来实现高效求解。核心思想如下: 1. 假设当前最优解大小为 \(k\),即尝试寻找是否存在一个大小为 \(k\) 的合法子集。 2. 枚举每一个可能作为起点的节点并将其加入候选子集。 3. 对剩余部分执行基于 BFS/DFS 的图遍历操作,在过程中动态调整其他节点的状态以确保整体合法性。 4. 如果某次试探能够成功构建符合条件的大规模子集,则更新答案;反之则降低目标值重新测试直至收敛至最佳结果。 这种方法利用了贪心策略配合回溯机制来逐步逼近全局最优点[^1]。 #### 实现细节说明 ##### 数据结构设计 定义三个主要数组用于记录状态信息: - `color[]` : 存储每个顶点所分配到的具体色彩编号; - `used[]`: 表示某个定点是否已经被处理过; - `adjList[][]`: 记录邻接表形式表示的原始输入数据结构便于后续访问关联元素。 ##### 主要逻辑流程 ```python from collections import deque def check(k, n): def bfs(start_node): queue = deque([start_node]) used[start_node] = True while queue: u = queue.popleft() for v, c in adjList[u]: if not used[v]: # Assign opposite color based on edge constraint 'c' target_color = ('B' if c == 'A' else 'A') if color[u]==c else c if color[v]!=target_color and color[v]!='?': return False elif color[v]=='?': color[v]=target_color queue.append(v) used[v] =True elif ((color[u]==c)==(color[v]==('B'if c=='A'else'A'))): continue return True count=0 success=True for i in range(n): if not used[i]: temp_count=count+int(color[i]=='?' or color[i]=='A') if k<=temp_count: color_copy=color[:] if bfs(i): count=temp_count break else : success=False return success n,m=list(map(int,input().split())) colors=[['?']*m]*n for _ in range(m): a,b,c=input().strip().split() colors[int(a)-1].append((int(b),c)) low ,high,res=0,n,-1 while low<=high: mid=(low+high)//2 color=['?']*n used=[False]*n if check(mid,n): res=mid low=mid+1 else : high=mid-1 print(res) ``` 上述代码片段展示了完整的程序框架以及关键函数 `check()` 的内部运作方式。它接受参数 \(k\) 并返回布尔值指示是否有可行配置支持如此规模的选择[^2]。 #### 复杂度分析 由于采用了二分查找技术缩小搜索空间范围再加上单轮 DFS/BFS 时间复杂度 O(V+E),总体性能表现良好适合大规模实例运行需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值