zoukankan      html  css  js  c++  java
  • Jzoj5662 尺树寸泓

    平衡树的问题,很容易想到中序遍历

    那么我们给每一个节点记录一下中序遍历中它子树所在的区间,一次旋转显然只会改变两个节点的值

    对于询问我们用线段树区间求积就可以了

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 200010
    #define M 1000000007
    #define LL long long
    #define mid (l+r>>1)
    #define ls l,mid,x<<1
    #define rs mid+1,r,x<<1|1
    using namespace std;
    int clk,n,m,l[N],r[N],v[N];
    int w[N],wl[N],wr[N],p[N],s[N],rk[N],rt;
    int T[N<<2];
    inline void ps(int x){
    	s[x]=(s[l[x]]+s[r[x]]+v[x])%M;
    	wl[x]=(l[x]?wl[l[x]]:rk[x]);
    	wr[x]=(r[x]?wr[r[x]]:rk[x]);
    }
    inline void dfs(int x){
    	if(l[x]) dfs(l[x]);
    	w[++clk]=x; rk[x]=clk;
    	if(r[x]) dfs(r[x]);
    	ps(x);
    }
    inline void build(int l,int r,int x){
    	if(l==r){ T[x]=s[w[l]]; return; }
    	build(ls);
    	build(rs);
    	T[x]=((LL)T[x<<1]*T[x<<1|1])%M;
    }
    inline void update(int l,int r,int x,int p,int k){
    	if(l==r){ T[x]=k; return; }
    	if(p<=mid) update(ls,p,k); else update(rs,p,k);
    	T[x]=((LL)T[x<<1]*T[x<<1|1])%M;
    }
    inline LL query(int l,int r,int x,int L,int R){
    	if(L<=l && r<=R) return T[x];
    	LL ans=1;
    	if(L<=mid) ans=ans*query(ls,L,R)%M;
    	if(mid<R) ans=ans*query(rs,L,R)%M;
    	return ans;
    }
    int main(){
    	freopen("splay.in","r",stdin);
    	freopen("splay.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i){
    		scanf("%d%d%d",v+i,l+i,r+i);
    		p[l[i]]=i; p[r[i]]=i;
    	}
    	for(int i=1;i<=n;++i) if(!p[i]) rt=i;
    	dfs(rt); 
    	build(1,n,1);
    	for(int o,x,y;m--;){
    		scanf("%d%d",&o,&x);
    		if(o==2) printf("%lld
    ",query(1,n,1,wl[x],wr[x]));
    		else{
    			if(!o&&l[x]){
    				y=l[x]; o=p[x];
    				l[x]=r[y]; r[y]=x; 
    				if(l[x]) p[l[x]]=x; p[x]=y; p[y]=o;
    				if(o){
    					if(l[o]==x) l[o]=y; else r[o]=y;
    				} else rt=y;
    				ps(x); ps(y);
    				update(1,n,1,rk[x],s[x]);
    				update(1,n,1,rk[y],s[y]);
    			} else if(o&&r[x]){
    				y=r[x]; o=p[x];
    				r[x]=l[y]; l[y]=x;
    				if(r[x]) p[r[x]]=x; p[x]=y; p[y]=o;
    				if(o){
    					if(l[o]==x) l[o]=y; else r[o]=y;
    				} else rt=y;
    				ps(x); ps(y);
    				update(1,n,1,rk[x],s[x]);
    				update(1,n,1,rk[y],s[y]);
    			}
    		}
    	}
    } 

  • 相关阅读:
    _00020 妳那伊抹微笑_谁的异常最诡异第一期之 SqlServer RSA premaster secret error
    &lt;&lt;Python基础教程&gt;&gt;学习笔记 | 第12章 | 图形用户界面
    ubuntu 14.04 桌面版关闭图形界面
    (一)简单工厂模式
    JS学习笔记-数据类型
    【C#】报表制作&lt;机房重构&gt;
    [leetcode][math] Add Digits
    hibernate(三) 一对多映射关系
    hibernate(二)一级缓存和三种状态解析
    Hibernate(五)之一对多&多对一映射关系
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477107.html
Copyright © 2011-2022 走看看