[loj6498]农民
对每一个节点用二元组$(p,v)$表示,其中$p$是其是父亲的左(0)还是右(1)儿子,$v$是其父亲的点权
$x$合法当且仅当:对于其到根路径上所有$(0,v)$都有$a_{x}<v$、$(1,v)$都有$a_{x}>v$
用树链剖分+线段树来维护这些二元组,即求出$(0,v)$的区间最小值和$(1,v)$的区间最大值即可
对于翻转,即将区间内(是$k$的子树除去$k$的部分)所有$(p,v)$变为$(p\oplus 1,v)$,即区间修改,并再维护$(0,v)$的区间最大值和$(1,v)$的区间最小值即可
(另外翻转后会改变区间,可以再开一棵线段树记录一下每一个点是否被翻转)
时间复杂度为$o(q\log^{2}n)$

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define L (k<<1)
5 #define R (L+1)
6 #define mid (l+r>>1)
7 #define pii pair<int,int>
8 #define fi first
9 #define se second
10 int rt,n,m,p,x,y,a[N],vis[N],ch[N][2],fa[N],sz[N],son[N],dfn[N],top[N],P[N<<2],tag[N<<2];
11 pii f[N<<2][2];
12 void dfs1(int k,int f){
13 if (!k)return;
14 fa[k]=f;
15 dfs1(ch[k][0],k);
16 dfs1(ch[k][1],k);
17 sz[k]=sz[ch[k][0]]+sz[ch[k][1]]+1;
18 son[k]=0;
19 if (sz[ch[k][0]]<sz[ch[k][1]])son[k]=1;
20 }
21 void dfs2(int k,int t){
22 if (!k)return;
23 dfn[k]=++dfn[0];
24 top[k]=t;
25 dfs2(ch[k][son[k]],t);
26 dfs2(ch[k][son[k]^1],ch[k][son[k]^1]);
27 }
28 void update_rev(int k,int l,int r,int x,int y){
29 if ((l>y)||(x>r))return;
30 if ((x<=l)&&(r<=y)){
31 P[k]^=1;
32 return;
33 }
34 update_rev(L,l,mid,x,y);
35 update_rev(R,mid+1,r,x,y);
36 }
37 int query_rev(int k,int l,int r,int x){
38 if (l==r)return P[k];
39 if (x<=mid)return query_rev(L,l,mid,x)^P[k];
40 return query_rev(R,mid+1,r,x)^P[k];
41 }
42 pii merge(pii x,pii y){
43 return make_pair(min(x.fi,y.fi),max(x.se,y.se));
44 }
45 void up(int k){
46 for(int i=0;i<2;i++)f[k][i]=merge(f[L][i],f[R][i]);
47 }
48 void upd(int k){
49 tag[k]^=1;
50 swap(f[k][0],f[k][1]);
51 }
52 void down(int k){
53 if (tag[k]){
54 upd(L);
55 upd(R);
56 tag[k]=0;
57 }
58 }
59 void update_val(int k,int l,int r,int x,int y,int p){
60 if (l==r){
61 f[k][0]=make_pair(y,0);
62 f[k][1]=make_pair(0x3f3f3f3f,y);
63 if (p)swap(f[k][0],f[k][1]);
64 return;
65 }
66 down(k);
67 if (x<=mid)update_val(L,l,mid,x,y,p);
68 else update_val(R,mid+1,r,x,y,p);
69 up(k);
70 }
71 void update_rev_val(int k,int l,int r,int x,int y){
72 if ((l>y)||(x>r))return;
73 if ((x<=l)&&(r<=y)){
74 upd(k);
75 return;
76 }
77 down(k);
78 update_rev_val(L,l,mid,x,y);
79 update_rev_val(R,mid+1,r,x,y);
80 up(k);
81 }
82 pii query_val(int k,int l,int r,int x,int y){
83 if ((l>y)||(x>r))return make_pair(0x3f3f3f3f,0);
84 if ((x<=l)&&(r<=y))return f[k][0];
85 down(k);
86 return merge(query_val(L,l,mid,x,y),query_val(R,mid+1,r,x,y));
87 }
88 void update(int k){
89 int p=query_rev(1,1,n,dfn[k]);
90 if (ch[k][0])update_val(1,1,n,dfn[ch[k][0]],a[k],p);
91 if (ch[k][1])update_val(1,1,n,dfn[ch[k][1]],a[k],p^1);
92 }
93 pii query(int k){
94 pii o=make_pair(0x3f3f3f3f,0);
95 while (k){
96 o=merge(o,query_val(1,1,n,dfn[top[k]],dfn[k]));
97 k=fa[top[k]];
98 }
99 return o;
100 }
101 int main(){
102 scanf("%d%d",&n,&m);
103 for(int i=1;i<=n;i++){
104 scanf("%d%d%d",&a[i],&ch[i][0],&ch[i][1]);
105 vis[ch[i][0]]=vis[ch[i][1]]=1;
106 }
107 for(int i=1;i<=n;i++)
108 if (!vis[i])rt=i;
109 dfs1(rt,0);
110 dfs2(rt,rt);
111 update_val(1,1,n,1,0x3f3f3f3f,0);
112 for(int i=1;i<=n;i++)update(i);
113 for(int i=1;i<=m;i++){
114 scanf("%d%d",&p,&x);
115 if (p==1){
116 scanf("%d",&a[x]);
117 update(x);
118 }
119 if (p==2){
120 update_rev(1,1,n,dfn[x],dfn[x]+sz[x]-1);
121 update_rev_val(1,1,n,dfn[x]+1,dfn[x]+sz[x]-1);
122 }
123 if (p==3){
124 pii o=query(x);
125 if ((a[x]<o.fi)&&(a[x]>o.se))printf("YES\n");
126 else printf("NO\n");
127 }
128 }
129 return 0;
130 }
[loj6498]农民的更多相关文章
- 【LOJ6498】「雅礼集训 2018 Day2」农民
题面 solution 直接暴力模拟,原数据可获得满分的成绩. 对于每个点,其父亲对其都有一个限制.故我们只需要判断当前点到根的路径上的限制是否都能满足即可. 考虑用树剖+线段树维护这个限制.考虑到翻 ...
- 连载《一个程序猿的生命周期》-《发展篇》 - 3.农民与软件工程师,农业与IT业
相关文章:随笔<一个程序猿的生命周期>- 逆潮流而动的“叛逆者” 15年前,依稀记得走出大山,进城求学的场景.尽管一路有父亲的陪伴,但是内心仍然畏惧.当父亲转身离去.准备回到 ...
- Android快速入门(转自 农民伯伯: http://www.cnblogs.com/over140/)
前言 这是前段时间用于公司Android入门培训的资料,学习Android三周时间收集整理的,时间仓促,希望能对像我这样还没入门就直接上项目的人一点帮助 :) 声明 欢迎转载,但请保留文章原始出处: ...
- [IT新应用]农民朋友的电子商务
今天通过http://olympiawa.gov/visitors.aspx olympia市的官网,到 http://www.olympiafarmersmarket.com/vendors-1/到 ...
- 转之农民伯伯 IHttpHandler中使用Session实现原理[ASP.NET | IHttpHandler |IRequiresSessionState]
前言 在实现自己的Handler的时候只需要继承IHttpHandler接口就行了,在Handler中使用Session时,只需要继承一下IRequiresSessionState就行了,到底为什么只 ...
- IT农民的开发人员工具清单(2013年)
IT行业日新月异,每天都不断变化着.作为一名混迹IT行业小有几个年头码农来说,不仅要时刻提高自身技术,也要不断更新自己开发工具.这些工具都是我吃饭的饭碗.饭碗旧了也是需要买个新的.转眼之间,已到201 ...
- 「雅礼集训 2018 Day2」农民
传送门 Description 「搞 OI 不如种田.」 小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\). 小 D 为自己种的树买了肥料,每天给树施肥. 可是几天后,小 D 却 ...
- 传播正能量——做一个快乐的程序员
引子 今天在博客园看到施瓦小辛格的文章我们搞开发的为什么会感觉到累,顿时有感而发.自己本来不擅长写文章,更不擅长写这种非技术性的文章,但是在思绪喷薄之际,还是止不住有很多话要说.针对从客观上说&quo ...
- EMC与地之重新认识地
记得在Mark的培训中,他手上拿了一个无线鼠标,然后问了一个很有意思的问题:“这个无线鼠标的地在哪里?同样,我们的手机没有和任何大地有接 触,那么这个地又在哪里呢?”这个问题确实很有意思,也确实让人很 ...
随机推荐
- WPF实现聚光灯效果
WPF开发者QQ群: 340500857 | 微信群 -> 进入公众号主页 加入组织 前言 效果仿照 CSS聚光灯效果 实现思路: 1. 设置底部Canvas背景色 #222222 . 2. ...
- iOS实现XMPP通讯(一)搭建Openfire
安装Openfire Openfire官网下载地址:https://igniterealtime.org/downloads/ (也是Spark客户端的下载地址) Openfire下载并安装后,打开系 ...
- linux下nginx编译安装、版本信息修改
环境 centos 7 安装依赖包 yum install -y gcc gcc-c++ glibc glibc-devel pcre pcre-devel zlib zlib-devel opens ...
- 请问:c语言中d=1/3*3.0;与d=1.0/3*3;d=?有什么区别
请问:c语言中d=1/33.0;与d=1.0/33;d=?有什么区别 d=1/33.0; 这时d=0,d=(1/3)3.0,这里1是整形,1/3也是整形,等于0,所以03.0=0 d=1.0/33; ...
- 《手把手教你》系列技巧篇(三十三)-java+ selenium自动化测试-单选和多选按钮操作-上篇(详解教程)
1.简介 在实际自动化测试过程中,我们同样也避免不了会遇到单选和多选的测试,特别是调查问卷或者是答题系统中会经常碰到.因此宏哥在这里直接分享和介绍一下,希望小伙伴或者童鞋们在以后工作中遇到可以有所帮助 ...
- 对比7种分布式事务方案,还是偏爱阿里开源的Seata,真香!(原理+实战)
前言 这是<Spring Cloud 进阶>专栏的第六篇文章,往期文章如下: 五十五张图告诉你微服务的灵魂摆渡者Nacos究竟有多强? openFeign夺命连环9问,这谁受得了? 阿里面 ...
- nssm.exe使用方法
nssm no-sucking service manager 1. 安装服务命令 nssm install <servicename> nssm install <servicen ...
- rocketMQ(一)基础环境
一.安装: http://rocketmq.apache.org/dowloading/releases/ https://www.apache.org/dyn/closer.cgi?path=roc ...
- 微信小程序的实现原理
一.背景 网页开发,渲染线程和脚本是互斥的,这也是为什么长时间的脚本运行可能会导致页面失去响应的原因,本质就是我们常说的 JS 是单线程的 而在小程序中,选择了 Hybrid 的渲染方式,将视图层和逻 ...
- Python课程笔记(十一)
一.线程与多线程 1.线程与进程 线程指的是 进程(运行中的程序)中单一顺序的执行流. 多个独立执行的线程相加 = 一个进程 多线程程序是指一个程序中包含有多个执行流,多线程是实现并发机制的一种有效手 ...