「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个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...
随机推荐
- #Leetcode# 985. Sum of Even Numbers After Queries
https://leetcode.com/problems/sum-of-even-numbers-after-queries/ We have an array A of integers, and ...
- 企业级分布式应用服务EDAS _Dubbo商业版_微服务PaaS平台 【EDAS Serverless 运维 创业】
企业级分布式应用服务EDAS _Dubbo商业版_微服务PaaS平台_分布式框架 - 阿里云https://www.aliyun.com/product/edas?source_type=yqzb_e ...
- Webbench、ab命令:做压力测试的工具和性能的监控工具
DDOS攻击:???DDOS概述:分布式拒绝服务(DDoS:Distributed Denial of Service)攻击,指借助于客户/服务器技术,将多个计算机联合起来作为攻击平台,对一个或多个目 ...
- CSS3 background-size属性兼容
background-size是CSS3新增的属性,但是IE8以下还是不支持 background-size:contain; // 缩小图片来适应元素的尺寸(保持像素的长宽比):background ...
- 剑指offer(5)
题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解法: 一个栈专门用来存数,当需要输出数时,把所有数倒到第二个栈,当然,若此时第二个栈中已经有数了(之前倒 ...
- java中级——二叉树比较冒泡和选择排序
上次我们说到二叉树排序比较,给出如下的题目 题目:创建五万个随机数,然后用分别用冒泡法,选择法,二叉树3种排序算法进行排序,比较哪种更快 废话不说直接上源码,可以看控制台结果 注意的是 需要我们需要上 ...
- WPF设置软件界面背景为MediaElement并播放视频
在我们的常见的软件界面设计中我们经常会设置软件的背景为SolidColorBrush或者LinerColorBrush.RadialGradientBrush 等一系列的颜色画刷为背景,有时我们也会使 ...
- vue bug & data type bug
vue bug & data type bug [Vue warn]: Invalid prop: type check failed for prop "value". ...
- 解决mybatis generator警告Cannot obtain primary key information from the database, generated objects may be incomplete
使用 mybatis generator 生成pojo.dao.mapper时 经常出现 Cannot obtain primary key information from the database ...
- swagger bug
https://blog.csdn.net/u011943534/article/details/81778125 处理swagger报错Could not resolve pointer: /def ...