Description
Stan is crazy about math. One day, he was confronted with an interesting integer function defined on positive integers, which satisfies f(1) = 1 and for every positive integer n, 3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n). He wanted to know, in the range of 1 to n, for a given k, what are f(i) mod k like. For simplicity, you could just calculate the number of i which satisfies f(i) mod k = t for every t in range of 0 to k – 1 as g(t), and tell Stan what is all g(x) xor up is.
Input
There are no more than 40 test cases. The first line of the input contains an integer T which means the number of test cases. Each test case contains two integer, n, k, just as mentioned earlier. Please note that n ≤ 1018, and k is a known Fermat prime -- that is to say, k is among { 3,5,17,257,65537} .
Output
For each test case, output the result of all g(x) xor up.
Sample Input
2 1 3 5 5
Sample Output
Stan is crazy about math. One day, he was confronted with an interesting integer function defined on positive integers, which satisfies f(1) = 1 and for every positive integer n, 3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n). He wanted to know, in the range of 1 to n, for a given k, what are f(i) mod k like. For simplicity, you could just calculate the number of i which satisfies f(i) mod k = t for every t in range of 0 to k – 1 as g(t), and tell Stan what is all g(x) xor up is.
Input
There are no more than 40 test cases. The first line of the input contains an integer T which means the number of test cases. Each test case contains two integer, n, k, just as mentioned earlier. Please note that n ≤ 1018, and k is a known Fermat prime -- that is to say, k is among { 3,5,17,257,65537} .
Output
For each test case, output the result of all g(x) xor up.
Sample Input
2 1 3 5 5
Sample Output
1 3
题目大意:
有个函数满足
3× f(n) × f(2n+1) = f(2n) × (1 + 3f(n)), f(2n) < 6×f(n)
且f(2n)<6*f(n)
输入n和k
另g(x)为f(n)%k==x的个数
x为0到k-1之间
求g(x)的异或和
因为有个小于号限定
所以f(2n)=3*f(n)
f(2n+1)=3*f(n)+1
然后我们可以迭代
设fx(n)为处理函数
对于n为偶数
则处理fx(n/2),然后将其中的余数*3和*3+1求出fx(n)
若n为奇数
则迭代fx(n-1)再暴力求出f(n)即可
P,S 因为没找到评测的地方所以正确性不保证
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
update:在hiho上交了。过了
<pre name="code" class="cpp">#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int k;
long long sx[65537],tsx[65537];
inline int cale(long long n)
{
if(n==1)
return 1;
else if(n%2==1)
return (3*cale((n-1)/2)+1)%k;
else
return 3*cale(n/2)%k;
}
inline void fx(long long n)
{
if(n==1)
{
sx[1]=1;
return ;
}
int i;
if(n%2==0)
{
fx(n/2);
memset(tsx,0,sizeof(tsx));
for(i=0;i<=k-1;i++)
{
tsx[i*3%k]+=sx[i];
tsx[(i*3+1)%k]+=sx[i];
}
for(i=0;i<=k-1;i++)
sx[i]=tsx[i];
sx[1]++;
sx[cale(n+1)]--;
}
else
{
fx(n-1);
sx[cale(n)]++;
}
}
int main()
{
freopen("k.in","r",stdin);
freopen("k.out","w",stdout);
int T;
scanf("%d",&T);
while(T>0)
{
T--;
int i;
long long n;
scanf("%lld%d",&n,&k);
memset(sx,0,sizeof(sx));
fx(n);
long long ans=0;
for(i=0;i<=k-1;i++)
ans=(ans^sx[i]);
// for(i=0;i<=k-1;i++)
// printf("%lld ",sx[i]);
// printf("\n");
printf("%lld\n",ans);
}
return 0;
}