HazelFan wants to build a rooted tree. The tree has nn nodes labeled 00 to n−1n−1, and the father of the node labeled ii is the node labeled ⌊i−1k⌋⌊i−1k⌋. HazelFan wonders the size of every subtree, and you just need to tell him the XOR value of these answers.
Input
The first line contains a positive integer T(1≤T≤5)T(1≤T≤5), denoting the number of test cases.
For each test case:
A single line contains two positive integers n,k(1≤n,k≤1018)n,k(1≤n,k≤1018).
Output
For each test case:
A single line contains a nonnegative integer, denoting the answer.
Sample Input
2
5 2
5 3
Sample Output
7
6
一个模拟。。很多因素导致比赛的时候没有写出来。。
改了改发现自己写着的时候想叉了,用一个递归记录最后一层的数量 那么从下往上回溯记录层数,那么最后一层对上面每一层棵树的影响是 re/(k^h) h是从下往上的层数,我从次底层开始回溯,分成三部分求和,第一部分是左边受到最后一层是满的的影响,第二部分是有余数的话对这一棵的影响,第三部分是右边没有受到最下面一层的影响
这里还有一个知识点:
求1异或到n
#include <iostream>
using namespace std;
unsigned xor_n(unsigned n)
{
unsigned t = n & 3;
if (t & 1) return t / 2u ^ 1;
return t / 2u ^ n;
}
int main(int argc, char* argv[])
{
const int N = 12;
cout<<xor_n(12)<<endl;
int n = 1,sum=0;
while (n<N+1)
{
sum = sum^n;
n++;
}
cout<<sum<<endl;
return 0;
}
真正的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,k;
ll h;
ll ans;
ll ss[110];
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a;
a*=a;
b>>=1;
}
return res;
}
ll dfs(ll sum,ll dep,ll k)
{
ss[dep]=sum;
if(sum+qpow(k,dep+1)>=n)
{
ll res=n-sum;
ans^=(res%2);
ll hh=res;
h++;
ll beishu=qpow(k,h);
ll no=hh/beishu;
ll yu=hh%beishu;
ll zong=qpow(k,dep);
if(yu){
zong=zong-no-1;
ll summ=0;
summ=(zong%2)*(ss[h-1]);
ans^=summ;
ll sum1=(no%2)*(ss[h]);
ans^=sum1;
ll sum3=0;
sum3=(ss[h-1])+res%beishu;
ans^=sum3;
}
else
{
zong=zong-no;
ll summ=0;
summ=(zong%2)*(ss[h-1]);
ans^=summ;
ll sum1=(no%2)*(ss[h]);
ans^=sum1;
}
return res;
}
ll res=dfs(sum+qpow(k,dep+1),dep+1,k);
ll hh=res;
h++;
ll bei=qpow(k,h);//就是它下面管辖和它自身的子树点数
ll no1=hh/bei;
ll yu1=hh%bei;
ll zong1=qpow(k,dep);
if(yu1){
zong1=zong1-no1-1;
ll summ1=0;
summ1=(zong1%2)*(ss[h-1]);
ans^=summ1;
ll sum11=(no1%2)*(ss[h]);
ans^=sum11;
ll sum33=0;
sum33=(ss[h-1])+res%bei;
ans^=sum33;
}
else
{
zong1=zong1-no1;
ll summ1=0;
summ1=(zong1%2)*(ss[h-1]);
ans^=summ1;
ll sum11=(no1%2)*(ss[h]);
ans^=sum11;
}
return res;
}
ll xor_n(ll n)
{
ll tt = n&3;
if(tt&1) return tt/2ll^1;
return tt/2ll^n;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
ans=0;
h=0;
scanf("%lld%lld",&n,&k);
if(k==1)
{
printf("%lld\n",xor_n(n));
continue;
}
dfs(1,0,k);
printf("%lld\n",ans);
}
}