• 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('
    ')
    #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");
    	}
    }
    
  • 相关阅读:
    【转】字典转模型需要注意的问题,以及第三方框架来处理字典转模型
    【转】使用SOAP访问Web服务
    Foundation框架2
    Foundation框架1
    什么是Protocol
    什么是Block
    什么么是Category
    ARC
    autorelease简介
    循环retain
  • 原文地址:https://www.cnblogs.com/Romeolong/p/10176182.html
Copyright © 2020-2023  润新知