hdu 6121 Build a tree(k叉树的异或和)

本文介绍了一种构建特定树状结构的算法,并通过实例详细解释了如何从最底层开始逐步构建到顶层的过程。该算法适用于解决某些类型的计算机科学问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Build a tree

题目链接:Build a tree

官方题解:
这里写图片描述

从最下层开始模拟到最上层就可以了。

除了最底层之外,每一层最多有三种节点,
第一种是以这个节点为根的树是满k叉树,第二种是不满的k叉树,第三种也是满k叉树,不过比第一种少了一层。

sz1表示第一种节点的子树大小(不过一旦没有了第一种节点,它就表示第二种节点),sum1表示有多少个这种节点
sz2,sum2,sz3,sum3同理

因此,边模拟边异或即可

代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
LL n,k;

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&k);
        if(k==1)//对于链来说要特判,否则直接模拟会TLE
        {
            switch(n%4)
            {
            case 1:
                printf("1\n");
                break;
            case 2:
                printf("%lld\n",n+1);
                break;
            case 3:
                printf("0\n");
                break;
            case 0:
                printf("%lld\n",n);
                break;
            }
        }
        else
        {
            LL tot,ans=0,sz1=0,sz2=0,sz3=0,sum1=0,sum2=0,sum3=0;
            for(tot=1; n; tot*=k)//找到最底层
            {
                n-=tot;
                if(n<tot*k)
                    break;
            }
            if(n)
            {
                sum1=n,sz1=1;
                if(n&1)
                    ans=1;//最后一层的结果
            }
            for(; tot>0; tot/=k)//从倒数第二层开始
            {
                if(sum1<k)
                    sz1=sum1*sz1+sz2+(k-sum1-sum2)*sz3+1,sum1=1,sz2=0,sum2=0;
                else
                {
                    if(sum1%k)
                        sz2=sum1%k*sz1+sz2+(k-sum1%k-sum2)*sz3+1,sum2=1;
                    else if(sum2)
                        sz2=sz2+(k-1)*sz3+1;
                    sz1=sz1*k+1;
                    sum1=sum1/k;
                }
                sz3=sz3*k+1;
                sum3=tot-sum1-sum2;
                if(sum1&1)
                    ans^=sz1;
                if(sum2&1)
                    ans^=sz2;
                if(sum3&1)
                    ans^=sz3;
            }
            printf("%lld\n",ans);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值