给你n,K,让你构造出一颗n个结点的完全K叉树,求所有结点子树大小的异或和。

先把n号结点到根的路径提取出来单独计算。然后这条路径把每一层分成了左右两部分,每一层的左侧和其上一层的右侧的结点的子树大小相同。

就可以容易计算每种大小的子树个数了。

当K等于1时,要单独讨论,答案为1 xor 2 xor ... xor n。这个打个表非常明显。

#include<cstdio>
using namespace std;
typedef long long ll;
ll n,K,pw[105];
int T;
int main(){
// freopen("1002.in","r",stdin);
// freopen("1002.out","w",stdout);
scanf("%d",&T);
for(;T;--T){
scanf("%lld%lld",&n,&K);
if(K==1){
if(n%4ll==0){
printf("%lld\n",n);
}
else if(n%4ll==1ll){
printf("%lld\n",1ll);
}
else if(n%4ll==2ll){
printf("%lld\n",n+1ll);
}
else{
printf("%lld\n",0ll);
}
continue;
}
pw[0]=1;
int j;
for(j=1;pw[j-1]<=n/K;++j){
pw[j]=pw[j-1]*K;
}
--j;
int e=j;
for(int k=1;k<=j;++k){
if(pw[k-1]>n-pw[k]){
e=k-1;
break;
}
pw[k]+=pw[k-1];
}
if(n==pw[e]){
--e;
}
ll i=n-1ll;
ll now=n;
ll nowsiz=1,sumnowsiz=1;
ll ans=1;
ll sheng=((n-pw[e])%K!=0 ? (n-pw[e])%K : K);
int E=e;
while(i!=0){
ll fa=(i-1)/K;
if((i-1ll-fa)%2ll==1ll){
ans^=sumnowsiz;
}
ans^=(sumnowsiz+sheng);
now=pw[e];
--e;
i=fa;
nowsiz*=K;
sumnowsiz+=nowsiz;
sheng=((n-pw[E])%(nowsiz*K)!=0 ? (n-pw[E])%(nowsiz*K) : (nowsiz*K));
}
printf("%lld\n",ans);
}
return 0;
}

最新文章

  1. 前端学PHP之文件操作
  2. jrebel实现tomcat热部署
  3. [转]在WPF中区别TextBlock和Label
  4. (01)javascript 数据类型
  5. 使用PowerQuery操作OData数据
  6. Google Chrome浏览器各版本直接下载地址
  7. xcode XCTest录制后测试出错临时解决方法
  8. 国内IT技术博客对比
  9. 【转】终于知道为什么我的mysql总是卸载的不干净以及老是找不到my.ini文件
  10. bzoj1311: 最优压缩
  11. HDU 3033 分组背包
  12. jsonp和事件发布监听
  13. 第二篇-FPGA学习之RoadMap
  14. HTML定位简介
  15. 手把手图文并茂教你用Android Studio编译FFmpeg库并移植
  16. Angular动画
  17. pygame学习之打印文本
  18. springboot+shiro+redis(单机redis版)整合教程-续(添加动态角色权限控制)
  19. Redis备份及回收策略
  20. Castle.Windsor依赖注入的高级应用_Castle.Windsor.3.1.0

热门文章

  1. centos 挂载数据盘
  2. java 连接MySQL的代码
  3. bzoj 1034 贪心
  4. hdu 1690 Bus System(Dijkstra最短路)
  5. Mimikatz.ps1本地执行
  6. charger related source code position
  7. leetcode 之Copy List with Random Pointer(23)
  8. xshell 如何连接服务器
  9. git+jenkins在windows机器上新建一个slave节点【转载】
  10. linux系统使用过程遇到的bug