• [CF960D] Full Binary Tree Queries


    Description

    给定一棵无限层的满二叉树,如果 (x) 是根,那么左孩子是 (2x),右孩子是 (2x+1)。现在有三种操作:将 (x) 所在层的所有节点整体向右循环移动 (k) 个单位;将 (x) 所在层的所有节点及其子树整体向右循环移动 (k) 个单位;输出 (x) 到根的路径。

    Solution

    实际上,由于访问到的层数不会超过 (63),我们只需要暴力记录每一层被循环移动的次数即可。对于第一种操作修改当层即可;对于第二种操作修改其后的所有层即可。

    对于询问,我们只需要反解出实际位置,就得到了路径上所有点的位置,再把位置换算回下标即可。本质上,我们只需要提供位置和下标之间的换算即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 63;
    
    int offset[N],n,t1,t2,t3,t4;
    
    int get_level(int p)
    {
        return log2(p);
    }
    
    int pos2id(int p)
    {
        int level=get_level(p);
        p=(p+(1ll<<level)+offset[level])%(1ll<<level)+(1ll<<level);
        return p;
    }
    
    int id2pos(int p)
    {
        int level=get_level(p);
        p=(p+(1ll<<level)-offset[level])%(1ll<<level)+(1ll<<level);
        return p;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin>>n;
        while(n--)
        {
            cin>>t1;
            if(t1==1)
            {
                cin>>t2>>t3;t3=-t3;
                int level=get_level(t2);
                offset[level]+=t3;
                offset[level]%=1ll<<level;
                offset[level]+=1ll<<level;
                offset[level]%=1ll<<level;
            }
            if(t1==2)
            {
                cin>>t2>>t3;t3=-t3;
                int level=get_level(t2);
                t3%=1ll<<level;
                t3+=1ll<<level;
                t3%=1ll<<level;
                for(int i=level;i<N;i++)
                {
                    offset[i]+=t3;
                    offset[i]%=1ll<<i;
                    offset[i]+=1ll<<i;
                    offset[i]%=1ll<<i;
                    t3*=2;
                }
            }
            if(t1==3)
            {
                cin>>t2;
                t2=id2pos(t2);
                /*cout<<"offset: ";
                for(int i=0;i<4;i++) cout<<offset[i]<<" ";
                cout<<endl;*/
                while(t2!=0)
                {
                    cout<<pos2id(t2)<<" ";
                    t2>>=1;
                }
                cout<<endl;
            }
        }
    }
    
    
  • 相关阅读:
    常用编码格式算法
    js显示当前时间
    客户端和服务器端乱码问题
    常用的小技巧
    开发jsp中常用标签
    java中的反射
    java中的单例设计模式
    java中的枚举类
    关于继承时构造方法的问题
    TCP三次握手和四次握手全过程 为什么要三次握手而不是二次握手?
  • 原文地址:https://www.cnblogs.com/mollnn/p/13599869.html
Copyright © 2020-2023  润新知