「雅礼集训 2018 Day2」农民
传送门
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!
「雅礼集训 2018 Day2」农民的更多相关文章
- 【LOJ6498】「雅礼集训 2018 Day2」农民
题面 solution 直接暴力模拟,原数据可获得满分的成绩. 对于每个点,其父亲对其都有一个限制.故我们只需要判断当前点到根的路径上的限制是否都能满足即可. 考虑用树剖+线段树维护这个限制.考虑到翻 ...
- LOJ6500. 「雅礼集训 2018 Day2」操作(哈希+差分)
题目链接 https://loj.ac/problem/6500 题解 区间取反 \(01\) 串的经典套路是差分.我们令 \(b_i = a_i\ {\rm xor}\ a_{i - 1}\)(\( ...
- 【卡常 bitset 分块】loj#6499. 「雅礼集训 2018 Day2」颜色
好不容易算着块大小,裸的分块才能过随机极限数据:然而这题在线的数据都竟然是构造的…… 题目描述 有 $n$ 个数字,第 $i$ 个数字为 $a_i$. 有 $m$ 次询问,每次给出 $k_i$ 个区间 ...
- #6499. 「雅礼集训 2018 Day2」颜色 [分块,倍增,bitset]
bitset压位,因为是颜色数,直接倍增,重合部分不管,没了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h> #d ...
- 「LOJ #6500」「雅礼集训 2018 Day2」操作
description LOJ 6500 solution 根据常有套路,容易想到将区间差分转化为异或数组上的单点修改,即令\(b_i=a_i \ xor\ a_{i-1}\), 那么将\([l,l+ ...
- 「雅礼集训 2017 Day2」解题报告
「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...
- #6034. 「雅礼集训 2017 Day2」线段游戏 李超树
#6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统 ...
- 【loj6034】「雅礼集训 2017 Day2」线段游戏
#6034. 「雅礼集训 2017 Day2」线段游戏 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:Special Judge 上传者: 匿名 题目描述 ...
- Loj #6503. 「雅礼集训 2018 Day4」Magic
Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...
随机推荐
- python3-使用requests模拟登录网易云音乐
# -*- coding: utf-8 -*- from Crypto.Cipher import AES import base64 import random import codecs impo ...
- 【洛谷 P4688】 [Ynoi2016]掉进兔子洞(bitset,莫队)
题目链接 第一道Ynoi 显然每次询问的答案为三个区间的长度和减去公共数字个数*3. 如果是公共数字种数的话就能用莫队+bitset存每个区间的状态,然后3个区间按位与就行了. 但现在是个数,bits ...
- OO第三单元(地铁,JML)单元总结
OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...
- ios手机app消息推送
h5+app项目,推送平台 " 个推 " 首先在manifest.json配置文件中点击模块权限配置,勾选push消息推送配置如图1-1 第二部在manifest.json配置文件 ...
- vue-cli3 一直运行 /sockjs-node/info
首先 sockjs-node 是一个JavaScript库,提供跨浏览器JavaScript的API,创建了一个低延迟.全双工的浏览器和web服务器之间通信通道. 服务端:sockjs-node(ht ...
- 修改ActiveMQ的内存大小
有时我们需要修改ActiveMQ的内存大小,防止内存溢出! 修改配置文件下-Xmx参数然后重启mq即可: /fs01/apache-activemq-5.15.0/bin/env ACTIVEMQ_O ...
- [LeetCode]1252. Cells with Odd Values in a Matrix
Given n and m which are the dimensions of a matrix initialized by zeros and given an array indices w ...
- unity 之 背包系统
此方法只是用于学习和实验所以细节不必要求 一.Ui设置. 画布配置如下: 布局: 说明: 画布里面首先建立一个panel命名为weapon1,在其内部再建立4个panel用于装备的卡槽,装备以imag ...
- Optaplanner与Google OR-Tools的区别
在规划相关的项目工作中,近两年我们的项目主要使用的是Optaplanner作为规划引擎,其核心也是一个的规划求解器(Solver).但作为另一个著名开源求解器Google OR-Tools(下称OR- ...
- destoon二次开发-用户名、邮箱、手机账号中间字符串以*隐藏 扩展
因为dt里面有用户名.邮箱.手机账号等,所以想办法进行隐藏保护用户隐私,所以个人就试着写了这个代码. 在api/extend.func.php文件下增加以下代码: //用户名.邮箱.手机账号中间字符串 ...