題意:
f(2n) = f(n)*3
f(2n+1) = f(n)*3+1
mod k以後,統計異或和
n 10^18
10^18數據量,一般都要轉化成二進制搞
據說還有數位dp的做法,並不會
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#define N 520
using namespace std;
typedef long long ll;
ll dp[6][62][70000];
ll f2[62];
ll nxt[6][70000][2];
ll tmp[2][70000];
ll ans[70000];
void init()
{
ll i, j, mod, t;
f2[0] = 1;
for( i = 1; i <= 60; i ++ )f2[i] = f2[i-1]*2;
for( j = 1; j <= 5; j ++ ){
if( j == 1 )mod = 3;
if( j == 2 )mod = 5;
if( j == 3 )mod = 17;
if( j == 4 )mod = 257;
if( j == 5 )mod = 65537;
for( i = 0; i < mod; i ++ ){
nxt[j][i][0] = 3*i%mod;
nxt[j][i][1] = (3*i+1)%mod;
}
dp[j][1][1] = 1;
for( i = 1; i <= 60; i ++ ){
for( t = 0; t < mod; t ++ ){
dp[j][i+1][nxt[j][t][0]] += dp[j][i][t];
dp[j][i+1][nxt[j][t][1]] += dp[j][i][t];
}
}// init 61 hang
for( i = 1; i <= 60; i ++ ){
for( t = 0; t < mod; t ++ ){
dp[j][i+1][t] += dp[j][i][t];
}
}
}
}
int main()
{
int i, j, t, p;
int T, id;
ll n, k, mod;
init();
scanf("%d", &T);
while( T -- ){
scanf("%lld%lld", &n, &k);
if( k == 3 )id = 1;
if( k == 5 )id = 2;
if( k == 17 )id = 3;
if( k == 257 )id = 4;
if( k == 65537 )id = 5;
for( i = 1; i <= 60; i ++ ){
if( n == f2[i]-1 ){
for( j = 0; j < k; j ++ ){
ans[j] = dp[id][i][j];
}
n = 0;
break;
}
else if( n > f2[i]-1 && n < f2[i+1]-1 ){
for( j = 0; j < k; j ++ ){
ans[j] = dp[id][i][j];
}
n -= f2[i]-1;
break;
}
}
ll res = 0;
if( !n ){
for( i = 0; i < k; i ++ ){
//printf("%lld ", ans[i]);
res ^= ans[i];
}
//puts("");
printf("%lld\n", res);
continue;
}
int fl = 1, cnt = 1, now = 1;
memset( tmp, 0, sizeof(tmp) );
tmp[1][1] = 1;
while( i > 0 ){
now ^= 1;
for( j = 0; j < k; j ++ )tmp[now][j] = 0;
for( j = 0; j < k; j ++ ){
tmp[now][nxt[id][j][0]] += tmp[now^1][j];
tmp[now][nxt[id][j][1]] += tmp[now^1][j];
}
if( n > f2[i]/2 ){
fl = nxt[id][fl][1];
n -= f2[i]/2;
}
else{
tmp[now][nxt[id][fl][1]] --;
fl = nxt[id][fl][0];
}
i --;
}
res = 0;
for( j = 0; j < k; j ++ ){
ans[j] += tmp[now][j];
//printf("%lld ",ans[j] );
res ^= ans[j];
}
//puts("");
printf("%lld\n", res);
}
}