设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]三叉神经树的更多相关文章

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

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

  2. 【BZOJ-3553】三叉神经树 树链剖分

    3553: [Shoi2014]三叉神经树 Time Limit: 160 Sec  Memory Limit: 256 MBSubmit: 347  Solved: 112[Submit][Stat ...

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

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

  4. [SHOI2014]三叉神经树

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

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

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

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

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

  7. P4332 [SHOI2014]三叉神经树

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

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

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

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

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

随机推荐

  1. 关于Linux环境变量

    查看全局变量:  printenv 查看单个环境变量的值可以用echo命令,必须在环境变量的名称前放一个$符号 如:

  2. IOS常用正则表达式

    IOS常用正则表达式 正则表达式用于字符串处理.表单验证等场合,实用高效.现将一些常用的表达式收集于此,以备不时之需. 匹配中文字符的正则表达式: [\u4e00-\u9fa5] 评注:匹配中文还真是 ...

  3. 【数据库】 防止sql注入,过滤敏感关键字

    private bool FilterIllegalChar(string sWord) { var result = false; var keyWord = @"select|inser ...

  4. java.lang.UnsupportedClassVersionError: org/xwiki/xxx : Unsupported major.minor version 51.0

    此类问题主要是因为Unsupported major.minor version 51.0. 原因是JDK版本不一致导致的问题.在web应用中碰到此问题. 应用中规定使用JDK7.0,本地JDK为6. ...

  5. 配置ogg异构mysql-oracle 单向同步

    从mysql到oracle和oracle到mysql差不多.大致步骤如下: 环境是:192.168.0.165 (Mysql ) —> 192.168.0.164 ( Oracle )想将mys ...

  6. Waiting Processed Cancelable ShowDialog (Release 2)

    namespace Test { using System; using System.Windows.Forms; static class Program { /// <summary> ...

  7. How to use the Visual Studio

    推荐一个提供VS配色方案的一个网站:StudioStyles,域名和网站同名:http://studiostyl.es/ 2. 整行剪切:Ctrl + X.光标不要选中任何文字,然后按这个快捷键就可以 ...

  8. update comboBox

    /// <summary> /// AutoCompleteComboBox /// </summary> public class AutoCompleteComboBox ...

  9. hdu 4568 Hunter(spfa预处理 + 状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568 思路:首先spfa预处理出每对宝藏之间的最短距离以及宝藏到边界的最短距离,然后dp[state] ...

  10. MyBatis入门案例 增删改查

    一.MyBatis入门案例: ①:引入jar包 ②:创建实体类 Dept,并进行封装 ③ 在Src下创建大配置mybatis-config.xml <?xml version="1.0 ...