HDU-6121 Build a tree - 2017 Multi-University Training Contest - Team 7(完全K叉树)

本文介绍了一种解决完全k叉树中所有节点的异或值的方法。通过递归遍历树结构,并利用快速幂运算,实现高效计算。特别关注了细节处理,确保算法正确性和效率。

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

题意:

给一个n个节点的完全k叉树,每个节点的值为以其为根节点的子树的节点数。问所有节点的异或值是多少。

思路:

思路很好想,注意细节就好。


代码:

#include <bits/stdc++.h>
#define LL long long
using namespace std;
int key;
LL n, k, ans, yu_sum, sum, num, up_k;
LL qpow(LL bas, int b)
{
	LL ans = 1;
	while(b)
	{
		if(b&1) ans *= bas;
		bas *= bas;
		b >>= 1;
	}
	return ans;
}
LL xor_n(LL n)  
{
    LL t = n & 3;  
    if(t & 1) return t/2ll^1; 
    return t/2ll^n;
}  
LL dfs(LL pre_sum, int deep)
{
	LL now_sum = qpow(k, deep);
	if(now_sum >= n-pre_sum) return n-pre_sum;
	LL res = dfs(pre_sum+now_sum, deep+1);
	if(key)
	{
		sum = num = res, yu_sum = res%k;
		LL sl = res/k;
		if(yu_sum) ++sl;
		ans ^= (res+now_sum-sl)%2;
		LL mn_num = num/k;
		ans ^= (mn_num%2)*(k+1);
		if(yu_sum) ans ^= yu_sum+1;
		key = 0, res = 0, num /= k, up_k = k;
		return res+now_sum;
	}
	LL mn_num = num/k; num /= k;
	if(num) up_k *= k;
	if(num == 0)
	{
		ans ^= (res/now_sum+sum+1);
		ans ^= ((now_sum-1)%2)*(res/now_sum+1);
		return res+now_sum;
	}
	if(now_sum == 1)
	{
		ans ^= (res+sum+1);
		return res+now_sum;
	}
	LL geshu = (sum-yu_sum)/up_k;
	if((sum-yu_sum)%up_k == 0)
	{
		ans ^= res/now_sum+yu_sum+1;
	}
	else
	{
		LL zans = (sum-yu_sum)-geshu*up_k;
		ans ^= (res/now_sum+zans+yu_sum+1);
	}
	ans ^= (geshu%2)*(res/now_sum+up_k+1);
	ans ^= ((now_sum-geshu-1)%2)*(res/now_sum+1);
	return res+now_sum;
}
int main()
{
	int t;
	//freopen("in.txt", "r", stdin);
	scanf("%d", &t);
	while(t--)
	{
		scanf("%lld %lld", &n, &k);
		ans = 0, key = 1, yu_sum = 0;
		if(k != 1) dfs(0, 0);
		else ans = xor_n(n);
		printf("%lld\n", ans);
	}
	return 0;
}


继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值