P4332-[SHOI2014]三叉神经树【LCT】
正题
题目链接: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】的更多相关文章
- P4332 [SHOI2014]三叉神经树(LCT)
Luogu4332 LOJ2187 题解 代码-Tea 题意 : 每个点有三个儿子 , 给定叶节点的权值\(0\)或\(1\)且支持修改 , 非叶子节点的权值为当有\(>=2\)个儿子的权值为\ ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT)
传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...
- P4332 [SHOI2014]三叉神经树
\(\color{#0066ff}{ 题目描述 }\) 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的 ...
- BZOJ 3553: [Shoi2014]三叉神经树 LCT
犯傻了,想到了如果是 0->1 的话就找最深的非 1 编号,是 1 -> 0 的话就找最深的非 0 编号. 但是没有想到这个东西可以直接维护. 假设不考虑叶子节点,那么如果当前点的值是 1 ...
- [BZOJ 3553][SHOI2014]三叉神经树
传送门(下面也有题面) 题目大意: 一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1. 每个节点的权 取决于其所有子节点中 哪种权出现的次数更多. 有若干次询问,每次询问修改一个叶子节点 ...
- 洛谷4322 SHOI2014 三叉神经树(LCT+思维)
好久之前做的题了QWQ 现在来补一发博客 一道神仙题啊..qwq 首先,我们可以看出来,我们如果对于每个点维护一个\(val\),表示他的直系儿子中有几个表现为1的. 那么\(val[x]>&g ...
- [SHOI2014]三叉神经树
题目描述 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的极大关注. SHOI 组织由若干个 SHOI ...
- BZOJ3553 : [Shoi2014]三叉神经树
设val[i]为i连出去的树突中输出值为0的个数 如果val[x]<=1,输出值为1,否则输出值为0 修改x就相当于val[f[i]]++或者val[f[i]]-- 用Link-cut Tree ...
- 3553: [Shoi2014]三叉神经树(树链剖分)
这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...
随机推荐
- mysql 优化面试题
第一方面:30种mysql优化sql语句查询的方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by涉及的列上建立索引. 2.应尽量避免在 where 子句中使用 ...
- log4j.properties配置文件及详解
log4j配置文件有三个主要的组件:Logger,Appender和Layout,分别为日志类型,日志输出目的地,日志输出格式. 1. 配置日志级别及appenderName log4j.rootLo ...
- WPF---数据模板(一)
一.场景模拟 假设我们现在有如下需求: 我们需要在ListBox中的每个Item中显示某个成员的姓名.年龄以及喜欢的颜色,点击Item的时候,会在右边显示详细信息,同时也想让ListBox的样式变得好 ...
- C语言定义常量
/* #define 标识符 #define day main中day=10;仅一次赋值*/ 错误 #define 标识符 常量值 #define day 10;
- 检测一个页面所用的时间的js
window.onload = function () { var loadTime = window.performance.timing.domContentLoadedEventEnd-wind ...
- 关于antd Select 限制选择个数的解决方案
应用场景描述: Select 被form 所包裹,且被getFieldDecorator修饰.所以值的改变应该通过form的setFieldsValue方法. Select模式肯定会是multiple ...
- zabbix 历史数据处理
问题描述 zabbix server 平稳运行有一段时间了,但是最近问题却来了,今天早上收到zabbixserver磁盘空间不足的告警.通过查看之后发现是大部分数据是zabbix 库的的数据 在进一步 ...
- Linux查看英伟达GPU信息
命令: nvidia-smi 结果:
- CSS001. 纯CSS实现瀑布流(纵向排序)
通过 Multi-columns 相关的属性 column-count.column-gap 配合 break-inside 来实现瀑布流布局. 首先对包裹图片的盒子增加样式,column-count ...
- Jsoup快速查询
一.selector选择器 二.Xpath查询