[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 }
View Code

 

posted @ 2021-01-27 10:06  PYWBKTDA  阅读(183)  评论(0编辑  收藏  举报