[LOJ2187] 「SHOI2014」三叉神经树(LCT)

题意给你一颗满三叉树,每个点权值定义为所有子节点权值和,叶子节点有一个属于[0,1][0, 1][0,1]的权值,每次修改一个叶子节点的权值,在修改后回答根节点的权值(n≤5×105n\le5\times10^5n≤5×105)。首先感谢Hany01的讲解,我们首先观察一下性质,发现每次修改只会修改修改点到根节点路径的一端前缀,而且这连续一端的位置权值是相同的,那么我们要找到这个前缀的末尾...
摘要由CSDN通过智能技术生成

题意

  • 给你一颗满三叉树,每个点权值定义为所有子节点权值和,叶子节点有一个属于 [ 0 , 1 ] [0, 1] [0,1]的权值,每次修改一个叶子节点的权值,在修改后回答根节点的权值( n ≤ 5 × 1 0 5 n\le5\times10^5 n5×105)。

首先感谢Hany01的讲解,我们观察一下性质,发现每次修改只会修改修改点到根节点路径的一端前缀,而且这连续一端的位置权值是相同的,那么我们要找到这个前缀的末尾,也就是第一个和前一段权值不同的位置,我们可以用LCT来维护这棵三叉树,辅助树中每个点保存一个点的子树内是否有权值非 0 0 0和非 1 1 1的点,那么我们修改就很好做了。

首先把修改点Access后Splay到根上,那么除了它之外它到根路径上的所有点都会在它的左子树,我们只需要在Splay上二分查找深度最大的位置即可,找到这个位置之后我们把这个点在原树中的父亲Access,也就相当于断了它和它子节点之间的联系,那么我们最后Splay修改点,在上面打标记就好了,复杂度 O ( n log n ) O(\text{n log n}) O(n log n),常数似乎还过得去,平均每个点跑了 500 500 500毫秒。

#include <bits/stdc++.h>

#define x first
#define y second
#define pb push_back
#define mp make_pair
#define inf (0x3f3f3f3f)
#define mem(a, b) memset(a, b, sizeof(a))
#define Rep(i, a) for (int i = 0; i < a; ++ i)
#define For(i, a, b) for (int i = a; i <= b; ++ i)
#define Forr(i, a, b) for (int i = a; i >= b; -- i)
#define Travel(i, x) for (int i = head[x]; i; i = nxt[i])

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

template<class T>inline T read(T &_) {
   
	T __ = getchar(), ___ = 1; _ = 0;
	for (; !isdigit(__); __ = getchar()) if (__ == '-') ___ = -1;
	for (; isdigit(__); __ = getchar(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值