hdu6121
hdu6121
题意
给出一棵树,\(0\) 为根节点,节点 \(i\) 的父节点标号是 \(\lfloor\frac{i-1}{k}\rfloor\),求所有子树大小的异或和。
分析
找规律。在纸上画个十几个一定可以找到规律(亲测有效)。
虽然数据很大,但是我们可以特判掉 \(k=1\) 的情况,同样有规律。
那么当 \(k > 1\) 时,树的叶子节点的数量的增长速度是很快的,而且叶子节点一定是连续分布的,也是说会有大量状态类似的子树,既然是求异或和,我们只需要判断有相同大小的子树的数量是否为奇数即可。
自底向上不断合并子树,记录几种状态的子树及其大小。
我这里分为三种:
- 可以独自向上合并而不需要借助其它节点的那些子树,也就是可以直接占据一个父节点
- 不能独自向上合并,必须借助第三类,或者由第一类多的子树转变而来
- 剩下的节点
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
int T;
scanf("%d", &T);
while(T--) {
ll n, k;
scanf("%lld%lld", &n, &k);
ll ans = 0;
if(k == 1) {
ll nn = n % 4;
if(nn == 0) ans = n;
else if(nn == 1) ans = 1;
else if(nn == 2) ans = n + 1;
else ans = 0;
} else {
ll sz = 1, lsz = 1;
int cnt = 1;
n--;
while(n > 0) {
sz = sz * k;
if(n - sz < 0) break;
n -= sz;
lsz = sz;
cnt++;
}
ll cnt1 = 0, cnt2 = 0, cnt3 = 0;
ll sz1 = 0, sz2 = 0, sz3 = 0;
if(n > 0) {
ans ^= (n & 1);
cnt1 = n / k; if(cnt1 > 0) sz1 = k + 1;
if(n % k > 0) { cnt2 = 1; sz2 = n % k + 1; }
}
cnt3 = lsz - cnt1 - cnt2;
sz3 = 1;
while(cnt--) {
ans ^= (cnt3 & 1) * sz3;
ans ^= (cnt1 & 1) * sz1;
ans ^= (cnt2 & 1) * sz2;
if(cnt1 / k == 0) {
sz2 += sz1 * cnt1 + 1;
if(cnt1 + cnt2 < k) {
cnt3 -= k - cnt1 - cnt2;
sz2 += (k - cnt1 - cnt2) * sz3;
cnt2 = 1;
}
cnt1 = 0;
sz1 = 0;
} else {
sz2 += sz1 * (cnt1 % k);
ll c = cnt1 % k + cnt2;
if(c < k) {
cnt3 -= k - c;
sz2 += (k - c) * sz3;
}
cnt2 = 1;
sz2++;
cnt1 = cnt1 / k;
sz1 = sz1 * k + 1;
}
cnt3 /= k;
sz3 = sz3 * k + 1;
if(cnt3 == 0) sz3 = 0;
}
}
printf("%lld\n", ans);
}
return 0;
}
hdu6121的更多相关文章
- hdu6121 Build a tree 模拟
/** 题目:hdu6121 Build a tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题意:n个点标号为0~n-1:节点i的父节点 ...
- 【hdu6121】 Build a tree 简单数学题
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6121 我好像推得挺久的诶..... 题目大意:给你一棵有$n$个点的树,根节点为$0$,对于其余节点 ...
- hdu6121 Build a tree
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6121 题面: Build a tree Time Limit: 2000/1000 MS (J ...
- 【暴力】hdu6121 Build a tree
给你n,K,让你构造出一颗n个结点的完全K叉树,求所有结点子树大小的异或和. 先把n号结点到根的路径提取出来单独计算.然后这条路径把每一层分成了左右两部分,每一层的左侧和其上一层的右侧的结点的子树大小 ...
- hdu6121 build a tree(树)
题解: 可以考虑每一层结点的子树大小 必定满足下面的情况,即 a,a,a,a,a,a,b,c,c,c,c........ 然后每一层依次往上更新,结果是不变的 一共有logn层,所以依次扫上去,统计结 ...
- 【思维】2017多校训练七 HDU6121 Build a tree
http://acm.hdu.edu.cn/showproblem.php?pid=6121 [题意] 询问n个结点的完全k叉树,所有子树结点个数的异或和是多少 [思路] 一棵完全K叉树,对于树的每一 ...
- 「2017 Multi-University Training Contest 7」2017多校训练7
1002 Build a tree(递归) 题目链接 HDU6121 Build a tree 有一棵n个点的有根树,标号为0到n-1,i号点的父亲是\(\lfloor\frac{i-1}{k}\rf ...
- 2017 Multi-University Training Contest - Team 7
HDU6121 Build a tree 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6121 题目意思:一棵 n 个点的完全 k 叉树,结点标号从 ...
随机推荐
- [Leetcode] Merge two sorted lists 合并两已排序的链表
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...
- BZOJ3671 [Noi2014]随机数生成器 【贪心】
题目链接 BZOJ3671 题解 模拟题意生成矩阵贪心从小选择即可 每选择一个,就标记其左下右上矩阵 由于每次都是标记一个到边界的矩阵,所以一旦遇到标记过就直接退出即可,可以保证复杂度 还有就是空间和 ...
- JUnit4.11 理论机制 @Theory 完整解读
最近在研究JUnit4,大部分基础技术都是通过百度和JUnit的官方wiki学习的,目前最新的发布版本是4.11,结合代码实践,发现官方wiki的内容或多或少没有更新,Theory理论机制章节情况尤为 ...
- mysql修改表中某个字段的默认值
Mysql中用SQL增加.删除字段,修改字段名.字段类型.注释,调整字段顺序总结 在网站重构中,通常会进行数据结构的修改,所以添加,删除,增加mysql表的字段是难免的,有时为了方便,还会增加修改 ...
- Javascript 的addEventListener()及attachEvent()区别分析
大家都知道事件的用法就是当某个事件(状况)被触发了之后就会去执行某个Function, 尤其是Javascript, 在当红AJAX的催化下, 了解Javascript的Event用法更加重要, 在这 ...
- Eclipse开发环境配置,打磨Eclipse,安装插件(适用3.4,3.5,3.6,3.7)
转载自:http://elf8848.iteye.com/blog/354035 打磨Eclipse -- 磨刀不误砍柴工 -------------------------------------- ...
- Java并发(9)- 从同步容器到并发容器
引言 容器是Java基础类库中使用频率最高的一部分,Java集合包中提供了大量的容器类来帮组我们简化开发,我前面的文章中对Java集合包中的关键容器进行过一个系列的分析,但这些集合类都是非线程安全的, ...
- Spring表达式语言之SpEL
•Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言. •语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL ...
- Python基础(7)闭包函数、装饰器
一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用 那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() ...
- Go 实现 soundex 算法
[转]http://www.syyong.com/Go/Go-implements-the-soundex-algorithm.html SOUNDEX 返回由四个字符组成的代码 (SOUNDEX) ...