Codeforces Round #474 D Full Binary Tree Queries 满二叉树操作

题解: 1、数据太大,一看到题就想该怎么存下这样的树(脑抽到想用数组或链表那种)。想想就可以发现树的每一层数据只是循环移动而没有改变,那么根据二叉树的特性是可以知道树某一层的所有值的。所以我们只需要62层(数组)来记录一下层的数据偏移量就行了。 2、执行操作1,就直接给层的偏移量deep[i]加上偏移值k(通过给k加上2e64然后对层起始值取模来保证偏移量为正值)。 3、执行操作2,要循环对层以及层以下所有层都加上偏移量k,维护正值和2同理,当前层的下一层的k要乘2。 4、特判查询数值1的情况。 5、先输出查询值,然后获得查询值在所在层的下标。对上层的下标计算直接除以2即可,计算每层值和相应的上层下标,值out用层起始值+下标-偏移量再取模得到,输出时要加上层起始值。 6、最重要的就是计算下标、偏移量、根据下标与偏移量计算每层对应的值这几条公式的推导。 7、由于数据量很大,所以pow的计算量很大,这里用数组保存直接使用。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 62;
const long long mod = pow(2,62);
long long deep[maxn];
long long real_mod[maxn];
void init(){
    real_mod[0] = 1;
    for(int i=1;i<maxn;i++)
        real_mod[i] = real_mod[i-1] << 1;
}

int main(){
    init();
    int q,t;
    long long x,k;
    scanf("%d",&q);
    while(q--){
        scanf("%d%lld",&t,&x);
        int lo = log2(x);//当前层
        if(t<3){
            scanf("%lld",&k);
            k += mod;
            if(t==1){
                k %= real_mod[lo];
                deep[lo] += k; //深度偏移量
                deep[lo] %= real_mod[lo]; //取模
            }
            else {
                k %= real_mod[lo];
                int tag = 0;
                for(int i=lo;i<maxn;i++){ //深度偏移
                    deep[i] += k * real_mod[i-lo];
                    deep[i] %= real_mod[i];
                }
            }
        }
        else {
            long long out,now = x + deep[lo]; //当前点的下标
            now %= real_mod[lo]; //当前点的下标
            if(x==1){
                printf("%lld\n",x);
                continue;
            }
            printf("%lld",x);
            now /= 2;
            lo--;
            for(;lo>=0;lo--){
                out = real_mod[lo]+now-deep[lo]; //out当前输出值
                out %= real_mod[lo];
                printf(" %lld",out+real_mod[lo]);
                now /= 2;
            }
            printf("\n");
        }
    }
    return 0;
}

    原文作者:满二叉树
    原文地址: https://blog.csdn.net/a912952381/article/details/79936496
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注