hdu4942 Game on S♂play(线段树)

10 篇文章 0 订阅
9 篇文章 0 订阅

传送门
考虑到中序遍历是不变的。
所以我们可以直接用线段树维护中序遍历的信息。
当然也可以用 s p l a y splay splay维护前序遍历的信息。
当然亦可以直接上 L C T LCT LCT自闭警告
注意多组数据记得要清零
代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
    static char buf[rlen],*ib,*ob;
    (ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
    return ib==ob?-1:*ib++;
}
inline int read(){
    int ans=0;
    char ch=gc();
    while(!isdigit(ch))ch=gc();
    while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
    return ans;
}
typedef long long ll;
const int N=2e5+5,mod=1e9+7;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void Add(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
inline void Dec(int&a,const int&b){a=a>=b?a-b:a-b+mod;}
inline void Mul(int&a,const int&b){a=(ll)a*b%mod;}
int n,q,son[N][2],vl[N],ss[N],fa[N],dfn[N],mnid[N],mxid[N],pred[N],tot=0;
namespace sgt{
    #define lc (p<<1)
    #define rc (p<<1|1)
    #define mid (l+r>>1)
    int mt[N<<2];
    inline void pushup(int p){mt[p]=mul(mt[lc],mt[rc]);}
    inline void build(int p,int l,int r){
        if(l==r){mt[p]=ss[pred[l]];return;}
        build(lc,l,mid),build(rc,mid+1,r),pushup(p);
    }
    inline void update(int p,int l,int r,int k,int v){
        if(l==r){mt[p]=v;return;}
        k<=mid?update(lc,l,mid,k,v):update(rc,mid+1,r,k,v),pushup(p);
    }
    inline int query(int p,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return mt[p];
        if(qr<=mid)return query(lc,l,mid,ql,qr);
        if(ql>mid)return query(rc,mid+1,r,ql,qr);
        return mul(query(lc,l,mid,ql,qr),query(rc,mid+1,r,ql,qr));
    }
    #undef lc
    #undef rc
    #undef mid
}
inline void pushup(int p){
    ss[p]=add(add(ss[son[p][0]],ss[son[p][1]]),vl[p]);
    mnid[p]=min(min(mnid[son[p][0]],mnid[son[p][1]]),dfn[p]);
    mxid[p]=max(max(mxid[son[p][0]],mxid[son[p][1]]),dfn[p]);
}
void dfs(int p){
    if(son[p][0])dfs(son[p][0]);
    pred[dfn[p]=++tot]=p;
    if(son[p][1])dfs(son[p][1]);
    pushup(p);
}
inline bool which(int x){return x==son[fa[x]][1];}
inline void rotate(int x){
    int t=which(x),y=fa[x];
    if(fa[y])son[fa[y]][which(y)]=x;
    fa[x]=fa[y],fa[y]=x,son[y][t]=son[x][t^1],son[x][t^1]=y;
    if(son[y][t])fa[son[y][t]]=y;
    pushup(y),pushup(x);
    sgt::update(1,1,n,dfn[x],ss[x]);
    sgt::update(1,1,n,dfn[y],ss[y]);
}
int main(){
    mxid[0]=-0x3f3f3f3f,mnid[0]=0x3f3f3f3f;
    for(ri TT=read(),tt=1;tt<=TT;++tt){
        n=read(),q=read(),tot=0;
        printf("Case #%d:\n",tt);
        fa[1]=0;
        for(ri i=1;i<=n;++i){
            vl[i]=read(),ss[i]=0;
            for(ri j=0;j<2;++j)son[i][j]=read(),fa[son[i][j]]=son[i][j]?i:0;
        }
        dfs(1);
        sgt::build(1,1,n);
        for(ri op,x,i=1;i<=q;++i){
            op=read(),x=read();
            if((op^2)&&son[x][op])rotate(son[x][op]);
            if(op==2)cout<<sgt::query(1,1,n,mnid[x],mxid[x])<<'\n';
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值