hdu4942线段树模拟rotate操作+中序遍历 回头再做

很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559

自己的代码不知道哪里出了点问题

/*
rotate操作不会改变树的中序遍历结果,将初始的树按中序遍历结果拍扁在线段树上,
线段树结点维护每个结点的子树范围,自身权值和子树权值
*/
#pragma comment(linker,"/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
#define mod 1000000007
#define ll long long
int ch[maxn][2],pre[maxn],n,m;
int dfs_clock,lx[maxn],rx[maxn],w[maxn],id[maxn];//结点在线段树中的位置
ll val[maxn];
void dfs(int u){
    if(ch[u][0]) dfs(ch[u][0]);//先遍历左子树
    id[u]=++dfs_clock;val[dfs_clock]=w[u];//访问当前结点
    if(ch[u][0]){
        lx[u]=lx[ch[u][0]];//左边界
        val[id[u]]+=val[id[ch[u][0]]];
    }
    else lx[u]=id[u];

    if(ch[u][1]) dfs(ch[u][1]);//在访问右子树
    if(ch[u][1]) {
        rx[u]=rx[ch[u][1]];//右边界
        val[id[u]]+=val[id[ch[u][1]]];
    } 
    else rx[u]=id[u];
    val[id[u]]%=mod;
}
inline void getinv(int x){
    if(ch[x][0]) lx[x]=lx[ch[x][0]];
    else lx[x]=id[x];
    if(ch[x][1]) rx[x]=rx[ch[x][1]];
    else rx[x]=id[x];
}

//线段树部分
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll mul[maxn<<2];
inline void pushup(int rt){
    mul[rt]=mul[rt<<1]*mul[rt<<1|1]%mod;
}
void build(int l,int r,int rt){
    if(l==r){mul[rt]=val[l];return;}
    int m=l+r>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
ll query(int L,int R,int l,int r,int rt){//查询区间[L,R]的乘积
    if(L<=l && R>=r) return mul[rt];
    int m=l+r>>1;
    ll res=1;
    if(L<=m) res=query(L,R,lson);
    if(R>m) res*=query(L,R,rson),res%=mod;
    return res;
}
void update(int pos,int l,int r,int rt,int val){
    if(l==r){mul[rt]=val;return;}
    int m=l+r>>1;
    if(pos<=m) update(pos,lson,val);
    else update(pos,rson,val);
    pushup(rt);
}

void rotate(int x,int kind){//右转是0,左转是1,和伸展树操作刚好相反。。
    int son=ch[x][kind];
    if(son==0) return;
    ch[x][kind]=ch[son][kind^1];
    if(ch[son][kind^1]) pre[ch[son][kind^1]]=x;
    if(pre[x]) ch[pre[x]][ch[pre[x]][1]==x]=son;
    pre[son]=pre[x];
    ch[son][kind^1]=x;
    pre[x]=son;

    val[id[x]]=(w[x]+val[id[ch[x][0]]]+val[id[ch[x][1]]])%mod;
    val[id[son]]=(w[son]+val[id[ch[son][0]]]+val[id[ch[son][1]]])%mod;
    update(id[x],1,n,1,val[id[x]]);//修改线段树上的值
    update(id[son],1,n,1,val[id[son]]);
    getinv(x);getinv(son);
}
int main(){
    int u,v,t,tcase=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        memset(ch,0,sizeof ch);
        memset(pre,0,sizeof pre);
        w[0]=val[0]=dfs_clock=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&w[i],&u,&v);
            ch[i][0]=u,ch[i][1]=v;
            if(u) pre[u]=i;
            if(v) pre[u]=i;
        }
        for(int i=1;i<=n;i++)if(pre[i]==0) {dfs(i);break;}
        build(1,n,1);
        printf("Case #%d:
",++tcase);
        while(m--){
            scanf("%d%d",&u,&v);
            if(u==2) printf("%lld
",query(lx[v],rx[v],1,n,1));
            else rotate(v,u);
        }
    }
}
原文地址:https://www.cnblogs.com/zsben991126/p/10060545.html