正题

题目链接:https://www.luogu.com.cn/problem/P4332


题目大意

给出\(n\)个点的一棵有根三叉树,保证每个点的儿子个数为\(3\)或者\(0\),每个叶子有一个权值\(0\)或\(1\),每个非叶子节点的权值是它儿子中权值较多的那个,每次修改一个叶子的权值,求根节点的权值。

\(1\leq n,q\leq 5\times 10^5\)


解题思路

修改一个节点会影响的权值显然是它到根节点路径上的一个前缀。

然后考虑什么样的节点会受到影响,如果\(0\)改为\(1\)那么一路上原来恰好为两个\(0\)的节点就会被修改,那么我们的思路是考虑找到这条路径上第一个\(1\)的个数不为\(1\)的节点。

而且考虑上修改的话十分的麻烦,因为\(O(n\log^2 n)\)过不去所以不考虑树剖,可以考虑一下\(LCT\)。

我们可以先联通修改点到根的节点,然后在\(Splay\)上二分出第一个不为\(1\)的节点,然后对于它和它的右子树暴力修改即可。

\(1\)改为\(0\)同理,维护第一个不为\(2\)的节点即可。

时间复杂度\(O(n\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=2e6+10;
int n,m,ans,fa[N],v[N],w1[N],w2[N],lazy[N],t[N][2];
vector<int> G[N];stack<int> s;
bool Nroot(int x)
{return fa[x]&&(t[fa[x]][0]==x||t[fa[x]][1]==x);}
bool Direct(int x)
{return t[fa[x]][1]==x;}
void PushUp(int x){
if(w1[t[x][1]])w1[x]=w1[t[x][1]];
else if(v[x]!=1)w1[x]=x;
else w1[x]=w1[t[x][0]];
if(w2[t[x][1]])w2[x]=w2[t[x][1]];
else if(v[x]!=2)w2[x]=x;
else w2[x]=w2[t[x][0]];
return;
}
void PushR(int x,int w)
{v[x]^=3;swap(w1[x],w2[x]);lazy[x]+=w;return;}
void PushDown(int x){
if(!lazy[x])return;
PushR(t[x][0],lazy[x]);
PushR(t[x][1],lazy[x]);
lazy[x]=0;return;
}
void Rotate(int x){
int y=fa[x],z=fa[y];
int xs=Direct(x),ys=Direct(y);
int w=t[x][xs^1];
if(Nroot(y))t[z][ys]=x;
t[x][xs^1]=y;t[y][xs]=w;
if(w)fa[w]=y;fa[y]=x;fa[x]=z;
PushUp(y);PushUp(x);return;
}
void Splay(int x){
int y=x;s.push(x);
while(Nroot(y))y=fa[y],s.push(y);
while(!s.empty())PushDown(s.top()),s.pop();
while(Nroot(x)){
y=fa[x];
if(!Nroot(y))Rotate(x);
else if(Direct(x)==Direct(y))
Rotate(y),Rotate(x);
else Rotate(x),Rotate(x);
}
return;
}
void Access(int x){
for(int y=0;x;y=x,x=fa[x])
Splay(x),t[x][1]=y,PushUp(x);
return;
}
void Updata(int x){
int op=(v[x]^=2);
x=fa[x];Access(x);Splay(x);
if(op){
if(w1[x]){
x=w1[x];Splay(x);
PushR(t[x][1],1);PushUp(t[x][1]);
v[x]++;PushUp(x);
}
else ans=!ans,PushR(x,1),PushUp(x);
}
else{
if(w2[x]){
x=w2[x];Splay(x);
PushR(t[x][1],-1);PushUp(t[x][1]);
v[x]--;PushUp(x);
}
else ans=!ans,PushR(x,-1),PushUp(x);
}
return;
}
void dfs(int x){
for(int i=0;i<G[x].size();i++){
int y=G[x][i];dfs(y);
v[x]+=(v[y]>>1);
}
PushUp(x);
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
fa[x]=fa[y]=fa[z]=i;
G[i].push_back(x);
G[i].push_back(y);
G[i].push_back(z);
}
for(int i=n+1;i<=3*n+1;i++)
scanf("%d",&v[i]),v[i]<<=1;
dfs(1);ans=v[1]>>1;
scanf("%d",&m);
while(m--){
int x;scanf("%d",&x);
Updata(x);
printf("%d\n",ans);
}
return 0;
}

P4332-[SHOI2014]三叉神经树【LCT】的更多相关文章

  1. P4332 [SHOI2014]三叉神经树(LCT)

    Luogu4332 LOJ2187 题解 代码-Tea 题意 : 每个点有三个儿子 , 给定叶节点的权值\(0\)或\(1\)且支持修改 , 非叶子节点的权值为当有\(>=2\)个儿子的权值为\ ...

  2. 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)

    洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...

  3. 洛谷P4332 [SHOI2014]三叉神经树(LCT)

    传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...

  4. P4332 [SHOI2014]三叉神经树

    \(\color{#0066ff}{ 题目描述 }\) 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的 ...

  5. BZOJ 3553: [Shoi2014]三叉神经树 LCT

    犯傻了,想到了如果是 0->1 的话就找最深的非 1 编号,是 1 -> 0 的话就找最深的非 0 编号. 但是没有想到这个东西可以直接维护. 假设不考虑叶子节点,那么如果当前点的值是 1 ...

  6. [BZOJ 3553][SHOI2014]三叉神经树

    传送门(下面也有题面) 题目大意: 一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1. 每个节点的权 取决于其所有子节点中 哪种权出现的次数更多. 有若干次询问,每次询问修改一个叶子节点 ...

  7. 洛谷4322 SHOI2014 三叉神经树(LCT+思维)

    好久之前做的题了QWQ 现在来补一发博客 一道神仙题啊..qwq 首先,我们可以看出来,我们如果对于每个点维护一个\(val\),表示他的直系儿子中有几个表现为1的. 那么\(val[x]>&g ...

  8. [SHOI2014]三叉神经树

    题目描述 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的极大关注. SHOI 组织由若干个 SHOI ...

  9. BZOJ3553 : [Shoi2014]三叉神经树

    设val[i]为i连出去的树突中输出值为0的个数 如果val[x]<=1,输出值为1,否则输出值为0 修改x就相当于val[f[i]]++或者val[f[i]]-- 用Link-cut Tree ...

  10. 3553: [Shoi2014]三叉神经树(树链剖分)

    这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...

随机推荐

  1. Future有返回值的线程

    //创建一个线程池 ExecutorService pool = Executors.newFixedThreadPool(100); //创建多个有返回值的任务 List<Future> ...

  2. 怎样在Qt中建立使用动态链接库

    参考网址: https://blog.csdn.net/q496713258/article/details/6990837 qt 的学习网址: http://c.biancheng.net/view ...

  3. react的每个方法为什么一定要bind this

    一开始学习react的时候就了解了react的每个方法都要bind(this)或者使用箭头函数绑定this的指向,到底是为什么要这么写呢,当时要学习的东西太多了就没在意,今天特别好奇(不搞懂不吃饭的态 ...

  4. 新东方APP技术团队建设

    作者:张建鑫, 曾任IBM高级软件架构师, 滴滴高级技术专家, 现任新东方集团高级技术总监 2019年注定是不平凡的一年,在俞敏洪老师对科技条线的密切关注下, 吴强老师亲自操盘了对产品技术条线的改革, ...

  5. pixhawk入门

    PX4 是软件名称,代码约30万行 Pixhawk是硬件名称 MissionPlanner是地面站名称 常见术语: WP:Way Point 航电 geofence:地理围栏 Rally Point: ...

  6. 机器学习基本概念:batch_size、epoch、 iteration

    batch_size 单次训练用的样本数,通常为2^N,如32.64.128... 相对于正常数据集,如果过小,训练数据就收敛困难:过大,虽然相对处理速度加快,但所需内存容量增加. 使用中需要根据计算 ...

  7. linux centos7 “git clone https://github.com/XXXXX” 报错解决方法

    2021-08-04 1. 问题描述 在执行以下命令时出现错误"正克隆到 'XXXXX'... fatal: unable to access 'https://github.com/lag ...

  8. 矩阵BFS

    leetcode 1091矩阵BFS 在一个 N × N 的方形网格中,每个单元格有两种状态:空(0)或者阻塞(1). 一条从左上角到右下角.长度为 k 的畅通路径,由满足下述条件的单元格 C_1, ...

  9. kubernetes 使用 PV 和 PVC 管理数据存储

    文章链接 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失--容器以干净的状态(镜像最初的状态)重 ...

  10. Python网络爬虫——京东商城商品列表

    Python_网络爬虫--京东商城商品列表 最近在拓展自己知识面,想学习一下其他的编程语言,处于多方的考虑最终选择了Python,Python从发布之初就以庞大的用户集群占据了编程的一席之地,pyth ...