传送门

FlashHu大佬太强啦%%%

首先,我们可以根据每一个点的权值为$1$的儿子的个数把每个点记为$0~3$,表示这一个点的点权

先考虑一下暴力的过程,假设从$0$变为$1$,先更改一个叶子结点,然后不断地往上更新,如果更改之后父亲的儿子中权值为$1$的儿子个数大于权值为$0$的儿子个数,那么就继续更新父亲,直到不能更新为止

不难发现,我们每一个更改的都是树上的一条链。而且,只有当点权为$1$时,才能因为修改使点权变为$2$,使输出改变,从而更新祖先。那么,我们需要的就是对于每一个节点,从它向上的连续的点权为$1$的一部分

如果是从$1$变为$0$同理,我们要维护从每一个节点向上的连续的点权为$2$的一部分

那么我们对于每一个节点,先access,然后记录splay中最深的点权不为$1$和$2$的点,然后把它给splay到根,再对右子树进行区间修改,对他自己单点修改

然后注意特判,如果整棵splay里都没有点权不为$1$或$2$的点,那么直接区间修改

然后怎么记录点权嘞?我们先把所有叶子结点的值*2,那么只有0和2两种值,然后每一个节点只要加上它所有叶子结点的值/2就是这个点的点权了

 //minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char sr[<<];int C=-;
inline void Ot(){fwrite(sr,,C+,stdout),C=-;}
inline void print(int x){
sr[++C]=x|,sr[++C]='\n';
}
const int N=,M=;
int fa[M],ch[N][],n1[N],n2[N],tag[N],v[M];
int d[N],q[M],h=,t,ans;
#define ls ch[x][0]
#define rs ch[x][1]
inline bool isrt(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pup(int x){
//先右儿子再自己最后左儿子
//因为&是短路运算符,有一个为假就会自动跳出
if(!(n1[x]=n1[rs])&&!(n1[x]=x*(v[x]!=))) n1[x]=n1[ls];
if(!(n2[x]=n2[rs])&&!(n2[x]=x*(v[x]!=))) n2[x]=n2[ls];
}
inline void pdown(int x,int t){
//被区间修改的要么都是1要么都是2,直接反转信息
v[x]^=,swap(n1[x],n2[x]),tag[x]+=t;
}
void all(int x){
if(!isrt(x)) all(fa[x]);
if(tag[x]) pdown(ls,tag[x]),pdown(rs,tag[x]),tag[x]=;
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isrt(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pup(y);
}
void splay(int x){
all(x);
for(int y=fa[x],z=fa[y];!isrt(x);y=fa[x],z=fa[y]){
if(!isrt(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pup(x);
}
inline void access(int x){
for(int y=;x;x=fa[y=x])
splay(x),rs=y,pup(x);
}
int main(){
// freopen("testdata.in","r",stdin);
int n=read();
for(int i=;i<=n;++i)
d[fa[read()]=fa[read()]=fa[read()]=i]=;
for(int i=n+;i<=*n+;++i) v[q[++t]=i]=read()<<;
while(h<=t){
int x=q[h++];if(x<=n) pup(x);
v[fa[x]]+=v[x]>>;
if(!(--d[fa[x]])) q[++t]=fa[x];
}
ans=v[]>>;
int q=read();
while(q--){
int x=read(),k=(v[x]^=)-;
access(x=fa[x]),splay(x);
if(~k?n1[x]:n2[x]){
splay(x=(~k?n1[x]:n2[x]));
pdown(rs,k),pup(rs);
v[x]+=k,pup(x);
}
else pdown(x,k),pup(x),ans^=;
print(ans);
}
Ot();
return ;
}

洛谷P4332 [SHOI2014]三叉神经树(LCT)的更多相关文章

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

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

  2. 洛谷4322 SHOI2014 三叉神经树(LCT+思维)

    好久之前做的题了QWQ 现在来补一发博客 一道神仙题啊..qwq 首先,我们可以看出来,我们如果对于每个点维护一个\(val\),表示他的直系儿子中有几个表现为1的. 那么\(val[x]>&g ...

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

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

  4. P4332 [SHOI2014]三叉神经树

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

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

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

  6. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  7. 【BZOJ2830/洛谷3830】随机树(动态规划)

    [BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...

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

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

  9. 洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP

    洛谷 P4284 [SHOI2014]概率充电器 概率与期望+换根DP 题目描述 著名的电子产品品牌\(SHOI\) 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米 ...

随机推荐

  1. Oracle 11g的7个服务详解

    成功安装Oracle 11g后,共有7个服务,这七个服务的含义分别为:1. Oracle ORCL VSS Writer Service:Oracle卷映射拷贝写入服务,VSS(Volume Shad ...

  2. appium-DesiredCapability详解与实战

    DesiredCapability对启动app至关重要,是启动app前的准备工作.如果配置错误,app不会成功启动. DesiredCapability有appium公共健值对.Android专有和I ...

  3. JS判断2个时间是否在同一周

    function isSameWeek(old, now) { var oneDayTime = 1000 * 60 * 60 * 24; var old_count = parseInt(+old ...

  4. python生成excel格式座位表

    脚本分两个文件: 1.生成二维随机列表:GenerateLocaltion.py 2.将列表导入excel文件:CreateExcel.py 先上GenerateLocaltion.py: impor ...

  5. php-fpm进程内存泄漏

    线上服务器内存报警 线上web8G内存的服务器,内存几乎吃光,top查看,发现php-fpm进程每个都是几十M,php-fpm配置static, 一共150个 解决 排除过程中,其他机器相同配置都没有 ...

  6. linux 故障:df -h统计磁盘空间占用太多,但又du -h找不到大的文件

    用lsof / | grep -i delete 从根目录定位打开的被删除的文件 如果定位到某文件占用空间很大 主要是因为我们在删除这个日志文件的时候是用rm -rf *.log这样的命令删除的,删除 ...

  7. [冬令营模拟]GTSG2018

    上学期没有去 GTSG,于是今天老师让我们来做一下 GTSG2018 Day1 & Day3 Day1 在上午当成一场考试来搞了,Day3 由于锅太多而且 T3 玄学而被放到下午自学... 上 ...

  8. ACM学习历程—Hihocoder 1290 Demo Day(动态规划)

    http://hihocoder.com/problemset/problem/1290 这题是这次微软笔试的第三题,过的人比第一题少一点,这题一眼看过去就是动态规划,不过转移方程貌似不是很简单,调试 ...

  9. POJ1995:Raising Modulo Numbers

    二进制前置技能:https://www.cnblogs.com/AKMer/p/9698694.html 题目传送门:http://poj.org/problem?id=1995 题目就是求\(\su ...

  10. Python知识点: os.popen

    用例:f = os.popen("%s %s %s" % ("pkg-config", " ".join(args), mod)) pope ...