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");
	}
}
posted @ 2018-12-25 20:07  Romeolong  阅读(287)  评论(0编辑  收藏  举报