BZOJ3553 : [Shoi2014]三叉神经树
设val[i]为i连出去的树突中输出值为0的个数
如果val[x]<=1,输出值为1,否则输出值为0
修改x就相当于val[f[i]]++或者val[f[i]]--
用Link-cut Tree维护这棵树,
每个节点维护val[x]、size[x](子树大小)、cnt1[x](子树里val[x]==1的个数)、cnt2[x](子树里val[x]==2的个数)
以val[f[i]]--为例:
设x=f[i]
access(x)取出x到根这条链
如果val[x]!=2,那么x的输出值不变,直接修改x即可
如果val[x]==2,那么影响到的肯定是一段连续的2以及最开头的2之前的那个点y
如果从根节点开始到x一直都是2,那么直接把这条链打上全部修改为1的标记即可
否则,因为这个具有单调性,所以可以二分这个y,
二分时方便起见二分深度,
对于当前二分到的mid,把深度为mid的点t splay上来
那么只要检验t的右子树是否符合cnt2[]==size[]就可以了
找到y之后splay(y),然后y的右子树里打上全部修改为1的标记,再把y单点修改即可
总复杂度$O(q\log^2n)$
#include<cstdio>
#define N 500010
int f[N*3],son[N][2],size[N],val[N],cnt1[N],cnt2[N],tag[N],a[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void swap(int&a,int&b){int c=a;a=b;b=c;}
inline bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
inline void same1(int x,int p){
if(!x)return;
val[x]=tag[x]=p;
if(p==1)cnt1[x]=size[x],cnt2[x]=0;else cnt2[x]=size[x],cnt1[x]=0;
}
inline void pb(int x){if(tag[x])same1(son[x][0],tag[x]),same1(son[x][1],tag[x]),tag[x]=0;}
inline void up(int x){
size[x]=size[son[x][0]]+size[son[x][1]]+1;
cnt1[x]=cnt1[son[x][0]]+cnt1[son[x][1]]+(val[x]==1);
cnt2[x]=cnt2[son[x][0]]+cnt2[son[x][1]]+(val[x]==2);
}
inline void rotate(int x){
int y=f[x],w=son[y][1]==x;
son[y][w]=son[x][w^1];
if(son[x][w^1])f[son[x][w^1]]=y;
if(f[y]){
int z=f[y];
if(son[z][0]==y)son[z][0]=x;
if(son[z][1]==y)son[z][1]=x;
}
f[x]=f[y];f[y]=x;son[x][w^1]=y;up(y);
}
inline void splay(int x){
int s=1,i=x,y;a[1]=i;
while(!isroot(i))a[++s]=i=f[i];
while(s)pb(a[s--]);
while(!isroot(x)){
y=f[x];
if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
rotate(x);
}
up(x);
}
inline void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y,up(x);}
inline int kth(int x,int k){
while(1){
if(k==size[son[x][0]]+1)return x;
if(k<=size[son[x][0]])x=son[x][0];else k-=size[son[x][0]]+1,x=son[x][1];
}
}
inline void dec(int x){
access(x);splay(x);
if(x==1||val[x]!=2){val[x]--;up(x);return;}
if(size[x]==cnt2[x]){same1(x,1);return;}
int y=0,l=1,r=size[x]-1,mid,t=x;
while(l<=r){
mid=(l+r)>>1;
splay(t=kth(t,mid));
if(cnt2[son[t][1]]==size[son[t][1]])y=t,r=mid-1;else l=mid+1;
}
splay(y);same1(son[y][1],1);val[y]--;up(y);
}
inline void inc(int x){
access(x);splay(x);
if(x==1||val[x]!=1){val[x]++;up(x);return;}
if(size[x]==cnt1[x]){same1(x,2);return;}
int y=0,l=1,r=size[x]-1,mid,t=x;
while(l<=r){
mid=(l+r)>>1;
splay(t=kth(t,mid));
if(cnt1[son[t][1]]==size[son[t][1]])y=t,r=mid-1;else l=mid+1;
}
splay(y);same1(son[y][1],2);val[y]++;up(y);
}
int n,i,x,j,g[N*3],nxt[N*6],v[N*6],ed,q,show[N*3];
inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x,int pre){
f[x]=pre;
if(x>n)return;
for(int i=g[x];i;i=nxt[i])if(v[i]!=pre){
dfs(v[i],x);
if(!show[v[i]])val[x]++;
}
show[x]=val[x]<=1;
}
int main(){
for(read(n),i=1;i<=n;i++)for(size[i]=1,j=0;j<3;j++)read(x),add(i,x),add(x,i);
for(i=n+1;i<=3*n+1;i++)read(show[i]);
dfs(1,0);
read(q);
while(q--){
read(x);
if(show[x])inc(f[x]);else dec(f[x]);show[x]^=1;
splay(1);
printf("%d\n",val[1]<=1);
}
return 0;
}
BZOJ3553 : [Shoi2014]三叉神经树的更多相关文章
- [BZOJ 3553][SHOI2014]三叉神经树
传送门(下面也有题面) 题目大意: 一颗有根树,每个非叶子节点都有三个子节点,每个节点的权为0/1. 每个节点的权 取决于其所有子节点中 哪种权出现的次数更多. 有若干次询问,每次询问修改一个叶子节点 ...
- 【BZOJ-3553】三叉神经树 树链剖分
3553: [Shoi2014]三叉神经树 Time Limit: 160 Sec Memory Limit: 256 MBSubmit: 347 Solved: 112[Submit][Stat ...
- 3553: [Shoi2014]三叉神经树(树链剖分)
这道题特别恶心,首先我们可以发现更改的就是出现连续的一或二,那么就用线段树+树链剖分找到这个范围 想到是不难想,就是打起来恶心罢了= = CODE: #include<cstdio> #i ...
- [SHOI2014]三叉神经树
题目描述 计算神经学作为新兴的交叉学科近些年来一直是学术界的热点.一种叫做SHOI 的神经组织因为其和近日发现的化合物 SHTSC 的密切联系引起了人们的极大关注. SHOI 组织由若干个 SHOI ...
- 洛谷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 ...
随机推荐
- Linux下第一次使用MySQL数据库,设置密码
在终端下输入:/etc/rc.d/init.d/mysqld status 查看MySQL状态,看看是否运行. 没有运行的话就输入:/etc/rc.d/init.d/mysqld start 这时,就 ...
- 16.迭代器模式(Iterator Pattern)
using System; namespace ConsoleApplication9 { class Program { /// <summary> /// 迭代器模式提供了一种方法顺序 ...
- **PHP中替换换行符
PHP中替换换行符 php 不同系统的换行不同系统之间换行的实现是不一样的linux 与unix中用 \nMAC 用 \rwindow 为了体现与linux不同 则是 \r\n所以在不同平台上 实现方 ...
- SQLAlchemy ORM之建表与查询
作了最基本的操作,找找感觉.. #coding=utf-8 from datetime import datetime from sqlalchemy import (MetaData, Table, ...
- 无废话ExtJs 入门教程九[数字字段:NumberField、隐藏字段Hidden、日期字段:DataFiedl]
无废话ExtJs 入门教程九[数字字段:NumberField.隐藏字段Hidden.日期字段:DataFiedl] extjs技术交流,欢迎加群(201926085) 继上第六节内容,我们在表单里加 ...
- poj 2236:Wireless Network(并查集,提高题)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 16065 Accepted: 677 ...
- 攻城狮在路上(叁)Linux(十三)--- 文件与目录的管理
一.查看文件与目录: 1.命令格式:ls [-aAdfFhilnrRSt] 目录名称; 2.参数说明: -a:显示所有的文件,包括隐藏文件(隐藏文件一般以.开头). -d:仅列出目录本身. -l:列出 ...
- 六款小巧的HTTP Server[C语言]
1.micro_httpd - really small HTTP server特点: 支持安全的 .. 上级目录过滤 支持通用的MIME类型 支持简单的目录 支持目录列表 支持使用 index.ht ...
- C# 获取wave文件信息【转】
public class WaveHelper { /// <summary> /// 数据流 /// </summary> private Stream m_WaveData ...
- -webkit-text-size-adjust
ios使用-webkit-text-size-adjust禁止调整字体大小 body{-webkit-text-size-adjust: 100%!important;} android使用以下代码, ...