zoukankan      html  css  js  c++  java
  • 并不对劲的loj6498. 「雅礼集训 2018 Day2」农民

    题目大意

    有一棵(n)个点有点权(w)(可能有重复)的二叉树。(m)次操作,操作种类如下:
    1.给出点(x),修改(x)的权值;
    2.给出点(x),交换它和它的子树内所有点的左右儿子;
    3.给出点(x),问从根出发是否可以用“当前点点权小于(w_x)就往右走,大于(w_x)就往左走,等于(w_x)就停”来走到点(x)
    (n,mleq 10^5;)

    题解

    当且仅当根到(x)路径上所有点满足“(x)在这个点左子树时点权大于(w_x),在右子树时点权小于(x)”时操作3的答案是“是”。
    相当于前一类点的最小值大于(x),后一类点的最大值大于(x)。可以用两棵线段树维护。
    操作2相当于两个线段树上的一些点。

    代码
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define view(u,k) for(int k=fir[u];~k;k=nxt[k])
    #define maxn 100007
    #define maxm 200007
    #define ls ch[u][0]
    #define rs ch[u][1]
    #define mi ((l+r)>>1)
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	if(x==0){putchar('0'),putchar('
    ');return;}
    	int f=0;char ch[20];
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	putchar('
    ');
    	return;
    }
    int n,m,a[maxn],son[maxn][2],wson[maxn],fa[maxn],siz[maxn],cntnd;
    int dfn[maxn],tim,top[maxn],tr[maxn],dep[maxn],mn[maxn<<3],mx[maxn<<3],ch[maxn<<3][2],rtmx,rtmn;
    int inf[2]={(int)(1e9+1),(int)(-1e9-1)};
    int lt(int x){return x&(-x);}
    void add(int x,int k){for(;x<=n;x+=lt(x))tr[x]^=k;return;}
    int ask(int x){int k=0;for(;x;x-=lt(x))k^=tr[x];return k;}
    void pu(int u)
    {
    	mx[u]=max(mx[ls],mx[rs]);
    	mn[u]=min(mn[ls],mn[rs]);
    	return;
    }
    int build(int l,int r)
    {
    	int u=++cntnd;
    	if(l==r){mn[u]=inf[0],mx[u]=inf[1];return u;}
    	ls=build(l,mi),rs=build(mi+1,r);pu(u);return u;
    }
    void adda(int u,int l,int r,int x,int k)
    {
    	if(l==r){mn[u]=mx[u]=k;return;}
    	if(x<=mi)adda(ls,l,mi,x,k);
    	else adda(rs,mi+1,r,x,k);
    	pu(u);return;
    }
    void chg(int & ua,int & ub,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y){swap(ua,ub);return;}
    	if(x<=mi)chg(ch[ua][0],ch[ub][0],l,mi,x,y);
    	if(y>mi)chg(ch[ua][1],ch[ub][1],mi+1,r,x,y);
    	pu(ua),pu(ub);return;
    }
    int aska(int u,int l,int r,int x,int y,int typ)//typ=0:mn
    {
    	if(x<=l&&r<=y){return typ?mx[u]:mn[u];}
    	int res=inf[typ];
    	if(x<=mi)res=aska(ls,l,mi,x,y,typ);
    	if(y>mi)res=typ?max(res,aska(rs,mi+1,r,x,y,typ)):min(res,aska(rs,mi+1,r,x,y,typ));
    	return res;
    }
    void getson(int u)
    {
    	siz[u]=1;
    	rep(i,0,1)if(son[u][i])
    	{
    		dep[son[u][i]]=dep[u]+1,fa[son[u][i]]=u,getson(son[u][i]),siz[u]+=siz[son[u][i]];
    		if(!wson[u]||siz[wson[u]]<siz[son[u][i]])wson[u]=son[u][i];
    	}
    }
    void gettop(int u,int anc)
    {
    	dfn[u]=++tim,top[u]=anc;
    	if(wson[u])gettop(wson[u],anc);
    	rep(i,0,1)if(son[u][i]&&son[u][i]!=wson[u])gettop(son[u][i],son[u][i]);
    }
    void gettr(int u)
    {
    	rep(i,0,1)if(son[u][i])
    	{
    		if(i)adda(rtmx,1,n,dfn[son[u][i]],a[u]);
    		else adda(rtmn,1,n,dfn[son[u][i]],a[u]);
    		gettr(son[u][i]);
    	}
    }
    int getnum(int x,int typ)
    {
    	int res=inf[typ];
    	while(x)
    	{
    		int tmp=aska(typ?rtmx:rtmn,1,n,dfn[top[x]],dfn[x],typ);
    		res=typ?max(res,tmp):min(res,tmp),x=fa[top[x]];
    	}
    	return res;
    }
    int main()
    {
    	n=read(),m=read();
    	rep(i,1,n)a[i]=read(),son[i][0]=read(),son[i][1]=read();
    	rtmx=build(1,n),rtmn=build(1,n);getson(1),gettop(1,1),gettr(1);
    	while(m--)
    	{
    		int f=read(),x=read();
    		if(f==1)
    		{
    			int y=read();a[x]=y;
    			rep(i,0,1)if(son[x][i])
    			{
    				int px=ask(dfn[son[x][i]]);
    				if(i^px){adda(rtmx,1,n,dfn[son[x][i]],a[x]);}
    				else {adda(rtmn,1,n,dfn[son[x][i]],a[x]);}
    			}
    		}
    		else if(f==2) 
    		{
    			chg(rtmn,rtmx,1,n,dfn[x]+1,dfn[x]+siz[x]-1),add(dfn[x]+1,1),add(dfn[x]+siz[x],1);
    		}
    		else 
    		{
    			int mxl=getnum(x,1),mnr=getnum(x,0);
    			if(mxl<a[x]&&mnr>a[x])puts("YES");
    			else puts("NO");
    		}
    	}
    	return 0;
    }
    
    一些感想

    为啥我打不过人???

  • 相关阅读:
    Quick-Cocos2d-x Lua脚本加密打包器
    Memcached保存sessionId
    windows操作系统重装后恢复svn仓库、tortoisesvn客户端信息、及权限信息的方法
    Fedora 17 开启ssh服务
    Spring mvc从一个controller到另一个controller
    FreeMarker设置编码格式
    又被数据坑了
    设置文件属性--C#点滴积累
    SQL点滴积累4--字符串替换功能Stuff()
    SQL点滴积累3--detete 删除的目标表数据与其他表有关联关系
  • 原文地址:https://www.cnblogs.com/xzyf/p/13143842.html
Copyright © 2011-2022 走看看