zoukankan      html  css  js  c++  java
  • 【LOJ6498】「雅礼集训 2018 Day2」农民

    题面

    solution

    直接暴力模拟,原数据可获得满分的成绩。

    对于每个点,其父亲对其都有一个限制。故我们只需要判断当前点到根的路径上的限制是否都能满足即可。

    考虑用树剖+线段树维护这个限制。考虑到翻转操作,我们需维护当前区间左儿子限制最小值/最大值和右儿子最小值/最大值。

    注意翻转操作会导致树的形态的改变。

    code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    namespace io {
    	const int SIZE=(1<<21)+1;
    	char ibuf[SIZE],*iS,*iT,c;
    #define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    	inline int gi (){
    		int x=0,f=1;
    		for(c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;
    		for(;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15); return x*f;
    	}
    } using io::gi;
    const int N=1e5+5,inf=1<<30;
    int n,m,a[N],ls[N],rs[N],size[N],son[N],top[N],dep[N],fa[N],id[N],ed[N],idx[N],tim,rt;
    int mxl[N<<2],mnl[N<<2],mxr[N<<2],mnr[N<<2];
    bool nr[N],isl[N],rev[N<<2],tg[N<<2];
    #define lx (x<<1)
    #define rx (x<<1|1)
    void dfs(int u)
    {
    	if(!u) return ; 
    	size[u]=1;
    	fa[ls[u]]=u,fa[rs[u]]=u;
    	dep[ls[u]]=dep[rs[u]]=dep[u]+1;
    	dfs(ls[u]),dfs(rs[u]);
    	son[u]=(size[ls[u]]>size[rs[u]]?ls[u]:rs[u]);
    }
    void dfs2(int u, int tp)
    {
    	if(!u) return ;
    	id[u]=++tim;
    	top[u]=tp, idx[tim]=u;
    	isl[ls[u]]=true;
    	if(son[u]==ls[u]) dfs2(ls[u],tp),dfs2(rs[u],rs[u]);
    	else dfs2(rs[u],tp),dfs2(ls[u],ls[u]);
    	ed[u]=tim;
    }
    void pushup(int x)
    {
    	mxl[x]=max(mxl[lx],mxl[rx]);
    	mnl[x]=min(mnl[lx],mnl[rx]);
    	mxr[x]=max(mxr[lx],mxr[rx]);
    	mnr[x]=min(mnr[lx],mnr[rx]);
    }
    void pushdown(int x)
    {
    	if(!rev[x]) return ;
    	rev[lx]^=1,rev[rx]^=1;
    	tg[lx]^=1,tg[rx]^=1;
    	swap(mxl[lx],mxr[lx]);
    	swap(mnl[lx],mnr[lx]);
    	swap(mxl[rx],mxr[rx]);
    	swap(mnl[rx],mnr[rx]);
    	rev[x]=0;
    }
    void upd(int x, int u, int w)
    {
    	if(u==1) mxl[x]=mxr[x]=-1,mnl[x]=mnr[x]=inf;
    	else if(isl[u]^tg[x]) mxl[x]=mnl[x]=w,mxr[x]=-1,mnr[x]=inf;
    	else mxr[x]=mnr[x]=w,mxl[x]=-1,mnl[x]=inf;
    }
    void build(int x, int l, int r)
    {
    	if(l==r)
    	{
    		upd(x,idx[l],a[fa[idx[l]]]);
    		return ;
    	}
    	int mid=l+r>>1;
    	build(lx,l,mid),build(rx,mid+1,r);
    	pushup(x);
    }
    void update(int x, int l, int r, int s, int w)
    {
    	if(l==r)
    	{
    		upd(x,idx[l],w);
    		return ;
    	}
    	pushdown(x);
    	int mid=l+r>>1;
    	s<=mid?update(lx,l,mid,s,w):update(rx,mid+1,r,s,w);
    	pushup(x);
    }
    void rever(int x, int l, int r, int sl, int sr)
    {
    	if(sl<=l&&r<=sr)
    	{
    		rev[x]^=1,tg[x]^=1;
    		swap(mxl[x],mxr[x]);
    		swap(mnl[x],mnr[x]);
    		return ;
    	}
    	pushdown(x);
    	int mid=l+r>>1;
    	if(sl<=mid) rever(lx,l,mid,sl,sr);
    	if(sr>mid) rever(rx,mid+1,r,sl,sr);
    	pushup(x);
    }
    pair<int,int> query(int x, int l, int r, int sl, int sr)
    {
    	if(sl<=l&&r<=sr) return make_pair(mnl[x],mxr[x]);
    	pushdown(x);
    	int mid=l+r>>1;
    	if(sr<=mid) return query(lx,l,mid,sl,sr);
    	else if(sl>mid) return query(rx,mid+1,r,sl,sr);
    	else
    	{
    		pair<int,int> ql=query(lx,l,mid,sl,sr),qr=query(rx,mid+1,r,sl,sr);
    		int ans_mnl,ans_mxr;
    		ans_mnl=min(ql.first,qr.first);
    		ans_mxr=max(ql.second,qr.second);
    		return make_pair(ans_mnl,ans_mxr);
    	}
    }
    bool check(int x)
    {
    	int ans_mnl=inf,ans_mxr=-1,w=a[x];
    	while(top[x]^top[rt])
    	{
    		pair<int,int> q=query(1,1,n,id[top[x]],id[x]);
    		ans_mnl=min(ans_mnl,q.first);
    		ans_mxr=max(ans_mxr,q.second);
    		x=fa[top[x]];
    	}
    	pair<int,int> q=query(1,1,n,id[rt],id[x]);
    	ans_mnl=min(ans_mnl,q.first);
    	ans_mxr=max(ans_mxr,q.second);
    	return (w<ans_mnl&&w>ans_mxr);
    }
    int main()
    {
    	n=gi(),m=gi();
    	for(int i=1;i<=n;++i) a[i]=gi(),ls[i]=gi(),rs[i]=gi(),nr[ls[i]]=nr[rs[i]]=true;
    	for(int i=1;i<=n;++i) if(!nr[i]) rt=i;
    	dfs(rt),dfs2(rt,rt),build(1,1,n);
    	while(m--)
    	{
    		int op=gi(),x=gi();
    		if(op==1)
    		{
    			int w=gi();
    			if(ls[x]) update(1,1,n,id[ls[x]],w);
    			if(rs[x]) update(1,1,n,id[rs[x]],w);
    			a[x]=w;
    		}
    		if(op==2) rever(1,1,n,id[x]+1,ed[x]);
    		if(op==3) puts(check(x)?"YES":"NO");
    	}
    }
    
  • 相关阅读:
    肩部肌肉劳损zt
    大屏幕手机上网页字体显示很小的问题
    SWT的Display
    The connection to adb is down, and a severe error has occured.
    [ZT]使用tmpfs缓存文件提高性能
    Mutex
    javascript阻塞加载问题【转】
    IE参考
    2台电脑网线对接注意的事项
    重建索引
  • 原文地址:https://www.cnblogs.com/farway17/p/10948240.html
Copyright © 2011-2022 走看看