LOJ6498 农民

一道不那么清真的数据结构
题目链接


首先对于没有操作\(2\)怎么做.
我们考虑对于每个节点,我们要让它小于到根节点道路上所有向左边的父亲节点权值,并且大于所有向右边的路的父亲权值.
我们令每条边的权值是它父亲的权值.
那么,我们用树剖线段树维护所有向右的边和向左的边即可.
现在有操作\(2\)怎么做呢?
所有向左的边会变成向右,向右的边会变成向左.
那么我们再维护两个值,在线段树上打一个\(lazytag\)即可.

代码如下
还是有点麻烦的.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#define N (100010)
#define inf (0x7f7f7f7f)
#define rg register int
#define Label puts("NAIVE")
#define spa print(' ')
#define ent print('\n')
#define rand() (((rand())<<(15))^(rand()))
typedef long double ld;
typedef long long LL;
typedef unsigned long long ull;
using namespace std;
inline char read(){
    static const int IN_LEN=1000000;
    static char buf[IN_LEN],*s,*t;
    return (s==t?t=(s=buf)+fread(buf,1,IN_LEN,stdin),(s==t?-1:*s++):*s++);
}
template<class T>
inline void read(T &x){
    static bool iosig;
    static char c;
    for(iosig=false,c=read();!isdigit(c);c=read()){
        if(c=='-')iosig=true;
        if(c==-1)return;
    }
    for(x=0;isdigit(c);c=read())x=((x+(x<<2))<<1)+(c^'0');
    if(iosig)x=-x;
}
inline char readchar(){
    static char c;
    for(c=read();!isalpha(c);c=read())
    if(c==-1)return 0;
    return c;
}
const int OUT_LEN = 10000000;
char obuf[OUT_LEN],*ooh=obuf;
inline void print(char c) {
    if(ooh==obuf+OUT_LEN)fwrite(obuf,1,OUT_LEN,stdout),ooh=obuf;
    *ooh++=c;
}
template<class T>
inline void print(T x){
    static int buf[30],cnt;
    if(x==0)print('0');
    else{
        if(x<0)print('-'),x=-x;
        for(cnt=0;x;x/=10)buf[++cnt]=x%10+48;
        while(cnt)print((char)buf[cnt--]);
    }
}
inline void flush(){fwrite(obuf,1,ooh-obuf,stdout);}
struct xds{
    int rmin,rmax,lmin,lmax,l,r; bool tag;
}a[N<<3];
int n,m,ch[N][2],w[N],dep[N],siz[N],fa[N];
int top[N],son[N],dfn[N],rdfn[N],ind;
void dfs(int u){
    int v=ch[u][0],maxsz=-1;
    siz[u]=1;
    if(v){
        dep[v]=dep[u]+1,fa[v]=u;
        dfs(v),siz[u]+=siz[v];
        if(siz[v]>maxsz)maxsz=siz[v],son[u]=v;
    }
    v=ch[u][1];
    if(v){
        dep[v]=dep[u]+1,fa[v]=u;
        dfs(v),siz[u]+=siz[v];
        if(siz[v]>maxsz)maxsz=siz[v],son[u]=v;
    }
}
void dfs2(int u){
    if(!u)return;
    ind++,dfn[u]=ind,rdfn[ind]=u;
    if(son[u])top[son[u]]=top[u],dfs2(son[u]);
    int v=ch[u][0];
    if(v!=son[u])top[v]=v,dfs2(v);
    v=ch[u][1]; if(v!=son[u])top[v]=v,dfs2(v);
}
void pushup(int x){
    a[x].rmin=min(a[x*2].rmin,a[x*2+1].rmin);
    a[x].rmax=max(a[x*2].rmax,a[x*2+1].rmax);
    a[x].lmin=min(a[x*2].lmin,a[x*2+1].lmin);
    a[x].lmax=max(a[x*2].lmax,a[x*2+1].lmax);
}
void pushdown(int x){
    if(!a[x].tag)return;
    a[x*2].tag^=1,a[x*2+1].tag^=1,a[x].tag=0;
    swap(a[x].lmin,a[x].rmin);
    swap(a[x].lmax,a[x].rmax);
}
bool chk(int u){
    return ch[fa[u]][0]==u;
}
void build(int l,int r,int x){
    a[x].l=l,a[x].r=r;
    if(l==r){
        a[x].lmin=a[x].rmin=inf;
        if(l==1)return;
        if(chk(rdfn[l]))a[x].lmax=a[x].lmin=w[fa[rdfn[l]]];
        else a[x].rmax=a[x].rmin=w[fa[rdfn[l]]];
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,x*2),build(mid+1,r,x*2+1);
    pushup(x);
}
void change(int k,int v,int x){
    if(!k)return;
    if(a[x].l==a[x].r){
        if(k==1)return;
        if(chk(rdfn[k]))a[x].lmax=a[x].lmin=w[fa[rdfn[k]]];
        else a[x].rmax=a[x].rmin=w[fa[rdfn[k]]];
        return;
    }
    pushdown(x);
    int mid=(a[x].l+a[x].r)>>1;
    if(k<=mid)change(k,v,x*2);
    else change(k,v,x*2+1);
    pushdown(x*2),pushdown(x*2+1);
    pushup(x);
}
void modify(int l,int r,int x){
    if(l>r)return;
    if(a[x].l==l&&a[x].r==r){
        a[x].tag^=1;
        pushdown(x);
        return;
    }
    pushdown(x);
    int mid=(a[x].l+a[x].r)>>1;
    if(r<=mid)modify(l,r,x*2);
    else if(l>mid)modify(l,r,x*2+1); 
    else modify(l,mid,x*2),modify(mid+1,r,x*2+1);
    pushdown(x*2),pushdown(x*2+1);
    pushup(x);
}
void query(int l,int r,int &lmin,int &rmax,int x){
    if(a[x].l==l&&a[x].r==r){
        lmin=a[x].lmin,rmax=a[x].rmax;
        return;
    }
    pushdown(x),pushdown(x*2),pushdown(x*2+1);
    int mid=a[x].l+a[x].r>>1;
    if(r<=mid)query(l,r,lmin,rmax,x*2);
    else if(l>mid)query(l,r,lmin,rmax,x*2+1);
    else{
        int lmin1,rmax1,lmin2,rmax2;
        query(l,mid,lmin1,rmax1,x*2);
        query(mid+1,r,lmin2,rmax2,x*2+1);
        lmin=min(lmin1,lmin2),rmax=max(rmax1,rmax2);
    }
}
bool query(int u){
    int lmin=inf,rmax=-inf,st=u;
    if(u==1)return 1;
    while(top[u]!=1){
        int lm=inf,rm=-inf;
        query(dfn[top[u]],dfn[u],lm,rm,1);
        lmin=min(lm,lmin);
        rmax=max(rm,rmax);
        u=fa[top[u]];
    }
    int lm=inf,rm=-inf;
    query(1,dfn[u],lm,rm,1);
    lmin=min(lm,lmin);
    rmax=max(rm,rmax);
    if(w[st]<lmin&&w[st]>rmax)return 1;
    else return 0;
}
int main(){
    read(n),read(m);
    for(int i=1;i<=n;i++)
    read(w[i]),read(ch[i][0]),read(ch[i][1]);
    dfs(1),top[1]=1,dfs2(1),build(1,n,1);
    while(m--){
        int op,x,y;
        read(op),read(x);
        if(op==1)read(y),w[x]=y,change(dfn[ch[x][0]],y,1),change(dfn[ch[x][1]],y,1);
        else if(op==2)modify(dfn[x]+1,dfn[x]+siz[x]-1,1);
        else if(query(x))puts("YES");else puts("NO");
    }
}

猜你喜欢

转载自www.cnblogs.com/Romeolong/p/10176182.html