Description
给出一个满k叉树的点数
Input
第一行一整数T表示用例组数,每组用例输入两个整数
Output
输出n个点权值异或和
Sample Input
2
5 2
5 3
Sample Output
7
6
Solution
找到不完全的子树,该子树左边的兄弟子树和右边的兄弟子树都是完全
注意k=1时要特判,此时ans=1 Xor 2 Xor .... Xor n
Code
#include<cstdio>
using namespace std;
typedef long long ll;
ll n,k;
ll Solve()
{
if(n<k+1)
{
if(n&1)return n;
return n+1;
}
ll Sum=1,p=1,Xor=1;
while((n-Sum)/k>=p)
{
p*=k;
Sum+=p;
Xor^=p;
}
ll L=(n-Sum-1)/p,R=k-L-1;
ll ans=n;
if(k&1)
{
if(L&1)ans^=Xor;
if(R&1)ans^=(Xor^p);
}
else
{
if(L&1)ans^=Sum;
if(R&1)ans^=(Sum-p);
}
n-=L*Sum+R*(Sum-p)+1;
return ans^Solve();
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d",&n,&k);
if(k==1)
{
if(n%4==0)printf("%I64d\n",n);
else if(n%4==1)printf("1\n");
else if(n%4==2)printf("%I64d\n",n+1);
else printf("0\n");
}
else
{
printf("%I64d\n",Solve());
}
}
return 0;
}