传送门

Description

「搞 OI 不如种田。」

小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\)。

小 D 为自己种的树买了肥料,每天给树施肥。

可是几天后,小 D 却发现树上有几个结点枯死了,他这才发现,自己买的肥料是二叉搜索树专用版。

二叉搜索树是一种二叉树,满足每个结点的权值大于左子树内所有点的权值,小于右子树内所有点的权值。

二叉搜索树专用版肥料是这么工作的:首先,假设所有节点权值互不相同(小 D 的二叉树可能不满足),每种权值对应一种肥料,所有肥料会从根进入树中,如果一种肥料对应的权值等于当前结点权值,这种肥料会被当前结点完全吸收,否则若肥料对应的权值小于当前结点权值,肥料会流向左子树,否则流向右子树,如果流向的子树为空,肥料只好流失蒸发了。显然,如果树是二叉搜索树,所有节点都能吸收到肥料。

小 D 觉得自己还能抢救一下,他会进行若干次操作,每次操作修改一个点的权值或者翻转一个子树(子树内所有节点左右儿子互换)。在操作过程中,他有时会想知道一个点当前是否能吸收到肥料,以决定之后如何操作,请你帮帮可怜的小 D 吧。

Solution

我们把每条边当成是一个元素,这个元素是一个可行的区间

对于一个点,它能够可行当且仅当它属于它到根节点路径上所有元素区间的并

可以求出dfs序后用线段树维护

对于取反操作,我们同时维护一下线段树上每个元素取反后的区间,修改时直接打标记就行

Code

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return x*f;
}
const int MN=1e6+5,inf=1<<30;
int n,m,a[MN],c[MN][2],dfn[MN],fdfn[MN],top[MN],siz[MN],mx[MN],fa[MN],R[MN];
bool ch[MN];
inline void dfs1(int x,int f)
{siz[x]=1;fa[x]=f;ch[x]=c[f][1]==x;if(c[x][0]) dfs1(c[x][0],x);if(c[x][1]) dfs1(c[x][1],x);siz[x]+=siz[c[x][0]]+siz[c[x][1]];mx[x]=siz[c[x][0]]>siz[c[x][1]]?0:1;
}
inline void dfs2(int x,int f,int tp)
{static int ind=0;dfn[x]=++ind;top[x]=tp;fdfn[ind]=x;if(c[x][mx[x]]) dfs2(c[x][mx[x]],x,tp);if(c[x][mx[x]^1]) dfs2(c[x][mx[x]^1],x,c[x][mx[x]^1]);R[x]=ind;
}
class Test
{bool rev[MN<<2],son[MN<<1];struct F{int l,r,_l,_r;}T[MN<<2];F merge(F o,F oo){return (F){max(o.l,oo.l),min(o.r,oo.r),max(o._l,oo._l),min(o._r,oo._r)};}bool P(int x,F y){return x>=y.l&&x<=y.r;}void Rev(int x){rev[x]^=1;son[x]^=1;std::swap(T[x].l,T[x]._l);std::swap(T[x].r,T[x]._r);}void pushdown(int x){if(!rev[x])return;Rev(x<<1);Rev(x<<1|1);rev[x]=0;}#define L fdfn[l]void update(int x,int l,int r,int u){if(l==r){if(son[x]) T[x].l=a[fa[L]]+1,T[x].r=inf,T[x]._l=1,T[x]._r=a[fa[L]]-1;else T[x]._l=a[fa[L]]+1,T[x]._r=inf,T[x].l=1,T[x].r=a[fa[L]]-1;return;}int mid=(l+r)>>1;pushdown(x);if(u<=mid) update(x<<1,l,mid,u);else update(x<<1|1,mid+1,r,u);T[x]=merge(T[x<<1],T[x<<1|1]);}void re(int x,int l,int r,int a,int b){if(a>b) return;if(l==a&&r==b){Rev(x);return;}int mid=(l+r)>>1;pushdown(x);if(b<=mid) re(x<<1,l,mid,a,b);else if(a>mid) re(x<<1|1,mid+1,r,a,b);else re(x<<1,l,mid,a,mid),re(x<<1|1,mid+1,r,mid+1,b);T[x]=merge(T[x<<1],T[x<<1|1]);}F Query(int x,int l,int r,int a,int b){if(a==l&&b==r) return T[x];int mid=(l+r)>>1;pushdown(x);if(b<=mid) return Query(x<<1,l,mid,a,b);else if(a>mid) return Query(x<<1|1,mid+1,r,a,b);return merge(Query(x<<1,l,mid,a,mid),Query(x<<1|1,mid+1,r,mid+1,b));}public:void Build(int x,int l,int r){if(l==r){son[x]=ch[L];if(L==1) T[x].l=T[x]._l=1,T[x].r=T[x]._r=inf;else if(ch[L]) T[x].l=a[fa[L]]+1,T[x].r=inf,T[x]._l=1,T[x]._r=a[fa[L]]-1;else T[x]._l=a[fa[L]]+1,T[x]._r=inf,T[x].l=1,T[x].r=a[fa[L]]-1;return;}int mid=(l+r)>>1;Build(x<<1,l,mid);Build(x<<1|1,mid+1,r);T[x]=merge(T[x<<1],T[x<<1|1]);}void upd(int x,int y){a[x]=y;if(c[x][0]) update(1,1,n,dfn[c[x][0]]);if(c[x][1]) update(1,1,n,dfn[c[x][1]]);}bool query(int x){int o=a[x];F ans=(F){1,inf,1,inf};while(x&&ans.l<=ans.r) ans=merge(ans,Query(1,1,n,dfn[top[x]],dfn[x])),x=fa[top[x]];return P(o,ans);}void reve(int x){re(1,1,n,dfn[x]+1,R[x]);}#undef L
}T;
int main()
{n=read();m=read();register int i,opt,x;for(i=1;i<=n;++i) a[i]=read(),c[i][0]=read(),c[i][1]=read();dfs1(1,0);dfs2(1,0,1);T.Build(1,1,n);while(m--){opt=read();x=read();if(opt==1) T.upd(x,read());if(opt==2) T.reve(x);if(opt==3) puts(T.query(x)?"YES":"NO");}return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/farmer_loj6498.html

「雅礼集训 2018 Day2」农民相关推荐

  1. #6034. 「雅礼集训 2017 Day2」线段游戏 李超树

    #6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...

  2. LibreOJ 6514. 「雅礼集训 2018 Day10」文明【虚树+LCA】

    6514. 「雅礼集训 2018 Day10」文明 [题目描述] 传送门 [题解] 考虑笨蛋的写法,可以用LCA求出1号和其他点的中点,然后DFS搜索Size大小即可,但是,复杂度显然要炸,但是我们会 ...

  3. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  4. [LOJ6515]「雅礼集训 2018 Day10」贪玩蓝月

    Description 要求维护一个双端队列,支持: 在队尾/队头添加一个体积为w,价值为v的物品 删除队尾/队头的物品 询问从所有物品中选出若干个,满足体积和对Mod取模后在[l,r]内的价值的最大 ...

  5. [LOJ]#6515. 「雅礼集训 2018 Day10」贪玩蓝月

    Solution 离线做法很简单,就是线段树分治,不过复杂度是 q m o d log ⁡ qmod\log qmodlog. 考虑在线做法,在线段树分治中,我们并没有利用到删除以及加入都只会在两端进 ...

  6. 「雅礼集训 2018 Day10」贪玩蓝月

    大渣好,我四渣渣辉,点一下,玩一年,装备不花一分钱,说话战斗,罩杯回收,找一基友,极限到手. 0 元 VIP,3 天满级,一秒一刀 999,装备全爆 666,广告做得再牛,不如进服遛一遛! 古天乐绿了 ...

  7. 数据结构二之线段树Ⅱ——KiKi‘s K-Number,ball,The Child and Sequence,「雅礼集训 2017 Day1」市场,Atlantis

    值域线段树+势能线段树+扫描线 KiKi's K-Number ball The Child and Sequence 「雅礼集训 2017 Day1」市场 Atlantis KiKi's K-Num ...

  8. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  9. #6029. 「雅礼集训 2017 Day1」市场(势能,区间除)

    #6029. 「雅礼集训 2017 Day1」市场 用线段树维护数列,区间上维护最大最小值,区间和还有标记,修改时,区间加直接做,而区间除时,递归到线段树上某一区间,如果这一操作等价于区间加(也就是最 ...

最新文章

  1. Oracle Performance Active Session History ASH图
  2. java什么是稳定排序,这可能是你听说过最快的稳定排序算法
  3. SpringSecurity remember功能基本实现
  4. qtdesigner设计表格_实例9 利用Qt Designer设计一个对话框
  5. 番茄花园win11 32位专业版镜像系统v2021.07
  6. linux-centos连网
  7. VSS (Visual Source Safe 2005) 用法详解(转载)
  8. 为Unreal4制作插件
  9. 库克:苹果商店收取30%佣金是应该的
  10. 5条简洁的JavaScript技巧
  11. 自制hdmi线一头改vga图_VGA连接线接口定义及引线焊接教程,VGA线不够长时可用网线代替?...
  12. 西游降魔之东去的西游
  13. 策略路由(本地策略和接口策略)
  14. 幼儿学习品质提升的培养策略问卷
  15. Landmark Guidance Independent Spatio-channel Attention and Complementary ContextInformationbased FER
  16. 【深度学习Deep Learning】资料大全
  17. latex排版[4]:子公式分别编号
  18. 建立您的启动:自定义会议视图
  19. 负反馈分析方法的本质
  20. 【新闻资讯】淘宝客达人:网赚盈利模式之淘宝客盈利技巧分享

热门文章

  1. webview session不失效_不懂HttpSession对象看这里--乐字节
  2. VB:谁终结了我的程序
  3. 几行VB代码拿下注册表
  4. 华为宣布智能计算战略,全栈全场景,当企业智能化转型加速器
  5. CIA的海外间谍,要如何完美避开AI的监控?
  6. 分享实录+PPT | 高通高级技术标准总监李俨:移动车联网技术解析
  7. php7 编译安装,添加扩展 pdo /usr/local/php/bin/phpize 发现没有 configure
  8. Android中定时器的3种实现方法
  9. Spark1.0新特性--Spark SQL
  10. php使用curl发送 json数据