「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」三叉神经树 解题报告的更多相关文章

  1. 「SHOI2014」三叉神经树

    「SHOI2014」三叉神经树 给你一颗由\(n\)个非叶子结点和\(2n+1\)个叶子结点构成的完全三叉树,每个叶子结点有一个输出:\(0\)或\(1\),每个非叶子结点的输出为自己的叶子结点中较多 ...

  2. 「ZJOI2019」线段树 解题报告

    「ZJOI2019」线段树 听说有人喷这个题简单,然后我就跑去做,然后自闭感++,rp++(雾) 理性分析一波,可以发现最后形成的\(2^k\)个线段树,对应的操作的一个子集,按时间顺序作用到这颗线段 ...

  3. 【LOJ】#2187. 「SHOI2014」三叉神经树

    题解 可以发现每次修改的是这个点往上一条连续的链,如果我要把1改成0,需要满足这一段往上的一部分都有两个1 如果我要把0改成1,需要满足这一段往上的部分有两个0 对于每个点记录1的个数,发现我们只会把 ...

  4. 「FJOI2016」神秘数 解题报告

    「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...

  5. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

  6. 「SCOI2016」背单词 解题报告

    「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...

  7. 「JLOI2015」管道连接 解题报告

    「JLOI2015」管道连接 先按照斯坦纳树求一个 然后合并成斯坦纳森林 直接枚举树的集合再dp一下就好了 Code: #include <cstdio> #include <cct ...

  8. 「SDOI2014」向量集 解题报告

    「SDOI2014」向量集 维护一个向量集合,在线支持以下操作: A x y :加入向量 \((x, y)\): Q x y l r:询问第 \(L\) 个到第 \(R\) 个加入的向量与向量 \(( ...

  9. 「NOI2015」寿司晚宴 解题报告

    「NOI2015」寿司晚宴 这个题思路其实挺自然的,但是我太傻了...最开始想着钦定一些,结果发现假了.. 首先一个比较套路的事情是状压前8个质数,后面的只会在一个数出现一次的再想办法就好. 然后发现 ...

随机推荐

  1. 后台管理系统之系统运行日志开发(Java实现)

    一,实现运行日志记录在文件中,并实现日志分包记录,项目出问题后方便定位分析.效果如图: 二,代码实现(springboot项目) 只需要在resources目录下新建:logback-spring.x ...

  2. Docker : Tomcat Clustering with Load Balancer (Tomcat and Nginx)

    Tomcat Clustering Series Part 5 : NginX as Load Balancer - Ramki Technical Bloghttps://www.ramkitech ...

  3. PHP之位运算符

    使用场景: 1) 判断奇数偶数 ; $i < ; $i++) { ){ echo $i.PHP_EOL; } } //输出所有奇数 2)快速修改状态 $status1 = ; $status2 ...

  4. vue前端框架面试问题汇总

    1.active-class是哪个组件的属性?嵌套路由怎么定义?答:vue-router模块的router-link组件. 2.怎么定义vue-router的动态路由?怎么获取传过来的动态参数? 答: ...

  5. hive JDBC客户端启动

    JDBC客户端操作步骤

  6. Springmvc架构

    框架结构如下图: 架构流程: 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理器映射器. 3.处理器映 ...

  7. app自动化测试Appium+python

    一.node.js安装 https://nodejs.org/en/download/ ##一直下一步 ###cmd查看 二.  .NET Framework安装 https://www.micros ...

  8. MSDN学习: 加密解密Config文件中的Sections( Encrypting and Decrypting Configuration Sections)

    https://msdn.microsoft.com/en-us/library/wfc2t3az(v=vs.100).aspx https://msdn.microsoft.com/en-us/li ...

  9. Visual Studio for Mac中的ASP.NET Core

    所以你们都听到了#Build 2017的消息,Mac上的Visual Studio已经被完全发布,是一般的.为了庆祝这个版本,我将在我的Mac上写几篇关于构建一些不同的.net应用的帖子. 正如你已经 ...

  10. A Simple Problem with Integers(线段树区间更新模板)

    最基本的线段树的区间更新及查询和 用tag(lazy)数组来“延缓”更新,查询或添加操作必须进行pushdown操作,即把tag从p传到lp和rp并清楚tag[p],既然得往lp和rp递归,那么就可以 ...