[SHOI2014]三叉神经树
题目描述
计算神经学作为新兴的交叉学科近些年来一直是学术界的热点。一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的极大关注。
SHOI 组织由若干个 SHOI 细胞构成,SHOI 细胞之间形成严密的树形结构。每个 SHOI 细胞都有且只有一个输出端,被称为轴突,除了一个特殊的、被称为根细胞的 SHOI 细胞的输出作为整个组织的输出以外,其余细胞的轴突均连向其上级 SHOI 细胞;并且有且只有三个接收端,被称为树突,从其下级细胞或者其它神经组织那里接收信息。SHOI 细胞的信号机制较为简单,仅有 00和 11两种。每个 SHOI 细胞根据三个输入端中 00和 11信号的多寡输出较多的那一种。
现在给出了一段 SHOI 组织的信息,以及外部神经组织的输入变化情况。请你模拟 SHOI 组织的输出结果。
题解
身体啊。
先考虑每一次修改能影响到的范围,这个比较简单,只能是这个点到根的路径上的所有点。
再次进一步的考虑,发现能够影响到的范围是一段连续的区间。
考虑为什么题目中给的是一颗每个点有三个儿子的树?如果一个节点时是1,那么它的1的儿子树时2或3,也就是d>>1=1,所以我们判断一个节点是否是被激活的就可以用度数/2来判断。
然后考虑某个叶子从1->0的时候,那么有修改的就是从这个叶子往上连续的一段2,和第一个不是2的点。
反之就是往上连续一段1和第一个不是1的点。
这是一个非常重要的性质,有了这个性质之后就可以二分最靠下的不是1/2的点,用&*%*#数据结构维护一下。
题解给的LCT做法非常喵。
我们不用二分,直接在LCT每个节点维护当前链中深度最深的不是1/2的点。
但是有个问题,这是一颗有根树,我们不能makeroot。
那么如何提取一条链?
假设我们的叶子为x,链顶为y,那么access&&splay(x)之后,当前的splay就是从叶子到根的一条链。
然后再splay(y)此时y的右子树就是我们要的链了。
我的写法如果第一个不是1/2的点是根的话要特判,为啥网上的题解都不同特判啊。。
代码
#include<iostream>
#include<cstdio>
#include<queue>
#define N 500009
#define ls ch[x][0]
#define rs ch[x][1]
using namespace std;
queue<int>q;
int ch[N][],fa[N],v[N*],rev[N],n1[N],n2[N],n,f[N*],du[N];
typedef long long ll;
inline ll rd(){
ll x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline bool ge(int x){return ch[fa[x]][]==x;}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pushup(int x){
n1[x]=n1[rs];if(!n1[x])n1[x]=(v[x]!=)?x:n1[ls];
n2[x]=n2[rs];if(!n2[x])n2[x]=(v[x]!=)?x:n2[ls];
}
inline void rotate(int x){
int y=fa[x],o=ge(x);
ch[y][o]=ch[x][o^];fa[ch[y][o]]=y;
if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y];
fa[y]=x;ch[x][o^]=y;pushup(y);pushup(x);
}
inline void pushdown(int x,int tag){
if(!x)return;
v[x]^=;swap(n1[x],n2[x]);rev[x]+=tag;
}
void _pushdown(int x){
if(!isroot(x))_pushdown(fa[x]);
if(rev[x])pushdown(ls,rev[x]),pushdown(rs,rev[x]),rev[x]=;
}
inline void splay(int x){
_pushdown(x);
while(!isroot(x)){
int y=fa[x];
if(isroot(y))rotate(x);
else rotate(ge(x)==ge(y)?y:x),rotate(x);
}
}
inline void access(int x){
for(int y=;x;y=x,x=fa[x])splay(x),ch[x][]=y,pushup(x);
}
int main(){
n=rd();int x,y,z;
for(int i=;i<=n;++i)f[i]=i;
for(int i=;i<=n;++i){
x=rd();y=rd();z=rd();
if(x>n)f[x]=i;else fa[x]=i,du[i]++;
if(y>n)f[y]=i;else fa[y]=i,du[i]++;
if(z>n)f[z]=i;else fa[z]=i,du[i]++;
}
for(int i=n+;i<=*n+;++i)v[i]=rd(),v[f[i]]+=v[i];
for(int i=;i<=n;++i)if(!du[i])q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
v[fa[u]]+=v[u]>>;
if(!--du[fa[u]])q.push(fa[u]);
}
int ans=,qu;
ans=v[]>>;
qu=rd();
while(qu--){
x=rd();v[x]^=;int ta=v[x]?:-;x=f[x];
// cout<<x<<" "<<n1[x]<<" "<<n2[x]<<endl;
access(x);splay(x);
if(ta==&&n1[x]){
x=n1[x];//cout<<"1"<<" haha "<<x<<endl;
splay(x);
pushdown(rs,ta);v[x]+=ta;pushup(x);
if(x==)ans=v[]>>;
}
else if(ta==-&&n2[x]){
x=n2[x];//cout<<"2"<<" haha "<<x<<endl;
splay(x);
pushdown(rs,ta);v[x]+=ta;pushup(x);
if(x==)ans=v[]>>;
}
else{
pushdown(x,ta);pushup(x);ans^=;
}
if(ans)puts("");else puts("");
}
return ;
}
[SHOI2014]三叉神经树的更多相关文章
- [BZOJ 3553][SHOI2014]三叉神经树
传送门(下面也有题面) 题目大意: 一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1. 每个节点的权 取决于其所有子节点中 哪种权出现的次数更多. 有若干次询问,每次询问修改一个叶子节点 ...
- 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 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- P4332 [SHOI2014]三叉神经树(LCT)
Luogu4332 LOJ2187 题解 代码-Tea 题意 : 每个点有三个儿子 , 给定叶节点的权值\(0\)或\(1\)且支持修改 , 非叶子节点的权值为当有\(>=2\)个儿子的权值为\ ...
- P4332 [SHOI2014]三叉神经树
\(\color{#0066ff}{ 题目描述 }\) 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT)
传送门 FlashHu大佬太强啦%%% 首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权 先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点 ...
- BZOJ 3553: [Shoi2014]三叉神经树 LCT
犯傻了,想到了如果是 0->1 的话就找最深的非 1 编号,是 1 -> 0 的话就找最深的非 0 编号. 但是没有想到这个东西可以直接维护. 假设不考虑叶子节点,那么如果当前点的值是 1 ...
- 洛谷4322 SHOI2014 三叉神经树(LCT+思维)
好久之前做的题了QWQ 现在来补一发博客 一道神仙题啊..qwq 首先,我们可以看出来,我们如果对于每个点维护一个\(val\),表示他的直系儿子中有几个表现为1的. 那么\(val[x]>&g ...
随机推荐
- ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门
一.前言 1.本教程主要内容 ASP.NET Core MVC 集成 EF Core 介绍&操作步骤 ASP.NET Core MVC 使用 EF Core + Linq to Entity ...
- org.springframework.beans.factory.NoUniqueBeanDefinitionException 导致原因之一
导致此异常原因很多,以下仅是针对其中一种因素的解决办法. 下面是DAO接口.Service接口.Service实现类的全路径名(全部定义在com.xxx.projetc包下) com.xxx.proj ...
- Nginx+uWSGI启动Django
在之前的几篇博客中对Django的功能做了初步实践,这里链接贴一下: Django的安装和启动 Django之--网页展示Hello World! Django之--通过MVC架构的html模板展示H ...
- 安装Linux内核源代码
系统:Ubuntu 18 CPU架构:AMD64 1,在终端输入:sudo apt install linux-source 命令 2,进入/usr/src/linux-source-4.15.0目录 ...
- LNMP时,出现502 Bad Gateway的错误提示
因为工作需要,要在ubuntu中安装LNMP环境,在这里,php是最新版本php7.1.一切都进展得很顺利,安装完成后,在浏览器中输入http://127.0.0.1/info.php,出现了502 ...
- Docker: 企业级镜像仓库Harbor部署(http)
Harbor离线安装包下载地址:https://github.com/goharbor/harbor Docker compose(安装harbor需要用到docker compose)下载地址:ht ...
- Python 函数调用&定义函数&函数参数
一.函数调用 在python中内置了很多函数,我们可以直接调用 .想要调用函数首先要知道函数的名称及包含的参数,还可以通过查看python官方的文档:https://docs.python.org/3 ...
- 英语进阶系列-A04-英语升级练习二
古诗背诵 要求:背诵和朗读,然后翻译成现代文,并绘制图像描述图中的内容,同时看看某些内容可以用什么单词替换,时间限制到15 minutes. 速记词汇系列 要求:将词汇快速朗读并记忆,时间为8 min ...
- JS第三部分--BOM浏览器对象模型
一.client系列:宽高边框 二.offset系列:偏移 三.scroll系列 四.BOM的介绍 4.1.打开新窗口 4.2.location对象(本地信息对象) 4.3.history对象 4.4 ...
- HTML,CSS---问题记录
1,,登录框input和标签垂直方向对不齐,咋解决? 给input框外套一层span标签,给span标签设置宽高,让它和左边或右边的标签对齐. 不要直接给input设置宽高,这样是对不齐的 2,套没有 ...