• 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]);
    			}
    		}
    	}
    } 

  • 相关阅读:
    向cmd中添加字体的方法
    学生成绩管理系统C++
    立即抢注我的免费1T云空间
    js原型
    step3 . day8数据结构之算法
    代码练习中的bug及修改方法
    step3 . day7数据结构之二叉顺序数的创建和二叉树的栈形式遍历
    step3 . day6数据结构之非线性表 满二叉树和不完全二叉树
    step3 . day5 数据结构之线性表 栈和队的应用-球钟问题
    step3 . day4 数据结构之线性表 栈和队
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477107.html
Copyright © 2020-2023  润新知