Divide by Zero 2018 and Codeforces Round #474 (Div. 1 + Div. 2, combined)D. Full Binary Tree Queries

二叉树的每一层进行旋转。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 65;
ll Move1[maxn];///正移动偏移量,方便知道原节点去了哪个位置

void op1(int lay,ll move,ll x,ll times)
{
    if(x) lay=log2(x)+1;      //多少层
    ll base=1ll<<(lay-1);//这一层有多少元素
    if(times==-1) move%=base;
    else move=((move%base)*(times%base))%base;
    //计算偏移量
    Move1[lay]=((Move1[lay]+move)%base+base)%base;
}

void op2(ll move,ll x){
    int lay=log2(x)+1;
    for(int i=lay,j=0;i<65;i++,j++){
        op1(i,move,0,1ll<<j);
    }
}

void op3(ll x){
    if(x==1ll){
        puts("1");
        return ;
    }
    printf("%lld",x);
    int lay=log2(x)+1;
    ll base=1ll<<(lay-1);
    //计算当前节点的位置
    ll pos=((x-base+Move1[lay])+base)%base+base;
    while(pos!=2ll&&pos!=3ll){
        pos/=2;
        lay=log2(pos)+1;
        base=1ll<<(lay-1);
        printf(" %lld",((pos-Move1[lay]-base)+base)%base+base);
    }puts(" 1");
}

int main(void)
{
    int n;
    scanf("%d",&n);
    while(n--){
        int cmd;
        scanf("%d",&cmd);
        ll x,k;
        if(cmd==1){
            scanf("%lld%lld",&x,&k); ///x是节点值,k是移动次数。
            op1(-1,k,x,-1);
        }else if(cmd==2){
            scanf("%lld%lld",&x,&k);
            op2(k,x);
        }else{
            scanf("%lld",&x);
            op3(x);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值