「SHOI2014」三叉神经树 解题报告
「SHOI2014」三叉神经树
膜拜神仙思路
我们想做一个类似于动态dp的东西,首先得确保我们的运算有一个交换律,这样我们可以把一长串的运算转换成一块一块的放到矩阵上之类的东西,然后拿数据结构维护。
但是考虑这个题,它最下面的那个运算的输入端只有两种可能,于是我们只需要讨论一下初始输入就完事了。
具体的,\(LCT\)每条实链维护一个\(yuu[i][0/1]\)表示实链底端的点输入为\(0/1\)后链头输出什么。
注意,这个链头指的是\(splay\)中那个点\(i\)的子树代表的那条链,也就是说链头是点\(i\)子树最左边的点。
那么单独的一个点没有实儿子一定输入\(0\),因为最深的儿子没有实儿子,于是整个链的输入也是\(0\)。
当然我们肯定需要维护一个虚儿子的信息,它可以使某一条链(splay中的某子树)的输出为\(1\)然后再传给它的父亲之类的
另外,\(yuu\)的全称是小糸侑(\(Koito \ Yuu\))
Code:
#include <cstdio>
#include <cctype>
#define ls ch[now][0]
#define rs ch[now][1]
#define fa par[now]
const int N=2e6+10;
template <class T>
void read(T &x)
{
x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int yuu[N][2],ch[N][2],par[N],bee[N],si[N],n,q;
void updata(int now)
{
yuu[now][0]=si[now]>1;
yuu[now][1]=si[now]>0;
if(rs)
{
if(yuu[rs][0]) yuu[now][0]=yuu[now][1];
else if(!yuu[rs][1]) yuu[now][1]=yuu[now][0];
}
if(ls)
{
if(yuu[now][0]) yuu[now][0]=yuu[now][1]=yuu[ls][1];
else if(!yuu[now][1]) yuu[now][0]=yuu[now][1]=yuu[ls][0];
else yuu[now][0]=yuu[ls][0],yuu[now][1]=yuu[ls][1];
}
}
int identity(int now){return ch[fa][1]==now;}
int isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
void Rotate(int now)
{
int p=fa,typ=identity(now);
connect(p,ch[now][typ^1],typ);
if(isroot(p)) connect(par[p],now,identity(p));
else fa=par[p];
connect(now,p,typ^1);
updata(p),updata(now);
}
void splay(int now)
{
for(;isroot(now);Rotate(now))
if(isroot(fa))
Rotate(identity(now)^identity(fa)?now:fa);
}
void access(int now)
{
for(int las=0;now;las=now,now=fa)
{
splay(now),si[now]-=yuu[las][0],si[now]+=yuu[rs][0];
rs=las,updata(now);
}
}
int head[N],to[N],Next[N],cnt;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
void dfs(int now)
{
if(now>n) return;
for(int i=head[now];i;i=Next[i])
dfs(to[i]),si[now]+=bee[to[i]];
bee[now]=yuu[now][0]=si[now]>1;
yuu[now][1]=si[now]>0;
}
int main()
{
read(n);
for(int x,i=1;i<=n;i++)
{
read(x),par[x]=i,add(i,x);
read(x),par[x]=i,add(i,x);
read(x),par[x]=i,add(i,x);
}
for(int i=n+1;i<=3*n+1;i++) read(bee[i]);
dfs(1);
read(q);
for(int x,now,i=1;i<=q;i++)
{
read(x),now=par[x];
access(now),splay(now);
bee[x]^=1;
si[now]+=bee[x]?1:-1;
updata(now);
putchar(yuu[now][0]?'1':'0'),putchar('\n');
}
return 0;
}
2019.2.24
「SHOI2014」三叉神经树 解题报告的更多相关文章
- 「SHOI2014」三叉神经树
「SHOI2014」三叉神经树 给你一颗由\(n\)个非叶子结点和\(2n+1\)个叶子结点构成的完全三叉树,每个叶子结点有一个输出:\(0\)或\(1\),每个非叶子结点的输出为自己的叶子结点中较多 ...
- 「ZJOI2019」线段树 解题报告
「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...
- 【LOJ】#2187. 「SHOI2014」三叉神经树
题解 可以发现每次修改的是这个点往上一条连续的链,如果我要把1改成0,需要满足这一段往上的一部分都有两个1 如果我要把0改成1,需要满足这一段往上的部分有两个0 对于每个点记录1的个数,发现我们只会把 ...
- 「FJOI2016」神秘数 解题报告
「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...
- 「ZJOI2016」大森林 解题报告
「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...
- 「SCOI2016」背单词 解题报告
「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...
- 「JLOI2015」管道连接 解题报告
「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...
- 「SDOI2014」向量集 解题报告
「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...
- 「NOI2015」寿司晚宴 解题报告
「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...
随机推荐
- Jenkins Installing and migration
JAVA_Zookeeper_hadoop - CSDN博客https://blog.csdn.net/wangmuming Installing Jenkins on Red Hat distrib ...
- css太极
自己用css做的太极,留个纪念. 用css做太极有很多种实现方法,我这种大概是最简单的了吧,因为div用得太多了,哈哈. 高级一点的应该是用伪类:before和:after去减少div的用量(手动滑稽 ...
- day 7-18 mysql case when语句
概述: sql语句中的case语句与高级语言中的switch语句,是标准sql的语法,适用于一个条件判断有多种值的情况下分别执行不同的操作. 首先,让我们看一下CASE的语法.在一般的SELECT中, ...
- 深入python的set和dict
一. collections中的abc 和list(Sequence)相似,都继承于Collection,添加了一些方法 二. dict的常见用法 (setdefault,defaultdict,__ ...
- Alertmanager 安装(k8s报警)
一.下载Alertmanager https://prometheus.io/download/ wget https://github.com/prometheus/alertmanager/rel ...
- SQL Server2012中如何通过bak文件还原SQL Server2012数据库
1 登陆完数据库后,不要新建数据库,直接点击“数据库”然后右击"还原数据库". 2 在"源"选项中选择"设备". 3 选择相应的bak文件并 ...
- ajax获得后台传来的一个json值,在js中获得其中的属性值
首先 ajax的dataType需要设置为json, 默认的text获取属性值在jquery3.2.1中尝试不成功 获得属性值的方式: 类似数组,键值对的方式 下面例子: 设置dataType为jso ...
- Python——管道通信
管道:双向通信 2个进程之间相互通信 from multiprocessing import Pipe,Process def func(conn1,conn2): conn2.close() whi ...
- codeforces158C
Cd and pwd commands CodeForces - 158C Vasya is writing an operating system shell, and it should have ...
- hdu-3068(最长回文子串-manacher)
题意:求一个字符串#include<iostream>#include<algorithm>#include<cstring>using namespace std ...