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 ...
随机推荐
- IOS关于录音,播放实现总结
//音频录制(标准过程5,9更新) 准备:导入AVFoundation框架及头文件 1 设置会话类型,允许播放及录音AVAudioSession *audioSession = [AVAudioSes ...
- 通过NSString初始化OC类
NSString *className = self.classNames[indexPath.section][indexPath.row]; BaseMapViewController *s ...
- mysqli扩展库的预处理技术 mysqli stmt
//预编译演示 //1,创建mysqli对象 $mysqli=new mysqli("localhost","root",""," ...
- 设置tomcat内存设定
Linux: 在/usr/local/apache-tomcat-/bin 目录下的catalina.sh添加: JAVA_OPTS='-Xms512m -Xmx1024m'要加"m&quo ...
- Delphi的枚举类型
参考:http://blog.csdn.net/kissdeath/article/details/2060573 Delphi程序不仅可以用于数值处理,还更广泛的用于处理非数值的数据.例如:性别.月 ...
- siblings 使用
//$(object).siblings().each(function () { // $(this).find("img").attr("class", & ...
- AJax中post与get请求注意事项
在使用ajax提交表单时,一定要区分提交按钮的形式和数据表头的设置,实例如下: GET请求: HTML代码: <!doctype html> <html lang="en& ...
- 《Spring 3.x 企业应用开发实战》目录
图书信息:陈雄华 林开雄 编著 ISBN 978-7-121-15213-9 概述: 第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识. 第2章:通过一个简单的例 ...
- Linux环境下使用perl编写CGI(httpd)
例子1: /var/www/cgi-bin/hello.cgi #!/usr/bin/perl print "Content-type: text/html\n\n"; print ...
- ASMCMD命令
安装好用的rlwrap工具,在环境变量里添加如下,就能实现显示当前路径(目录),目录补全的方便功能 alias asmcmd='rlwrap -r -i asmcmd –p' asmcmd>he ...