x^3x=2x
即x^2x=3x
即x^2x=x+2x
即x与2x的为1的位没有交
即x没有相邻的为1的位
那么第一位二进制数位DP,第二问矩乘即可
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
#include<map>
using namespace std;
#define MAXN 1010
#define MAXM 1010
#define INF 1000000000
#define eps 1e-8
#define MOD 1000000007
#define ll long long
struct mat{
ll x[3][3];
mat(){
memset(x,0,sizeof(x));
}
friend mat operator *(mat x,mat y){
int i,j,k;
mat z;
for(i=0;i<3;i++){
for(j=0;j<3;j++){
for(k=0;k<3;k++){
(z.x[i][j]+=x.x[i][k]*y.x[k][j])%=MOD;
}
}
}
return z;
}
};
ll n;
ll f[MAXN],g[MAXN],mi[MAXN];
ll ans=0;
int L;
mat A,B,C;
int main(){
int i;
f[0]=g[0]=mi[0]=1;
for(i=1;i<=62;i++){
mi[i]=mi[i-1]<<1;
f[i]=g[i-1];
g[i]=f[i-1]+g[i-1];
}
int tmp;
scanf("%d",&tmp);
while(tmp--){
scanf("%lld",&n);
ans=0;
for(L=62;~L;L--){
if(mi[L]<=n){
break;
}
}
bool flag=0;
for(L--;~L;L--){
if(!flag&&(n&mi[L])){
ans+=g[L];
}
if((n&mi[L])&&(n&mi[L+1])){
flag=1;
}
ans+=f[L];
}
if(!flag){
ans++;
}
printf("%lld\n",ans);
A=B=C=mat();
for(i=0;i<3;i++){
B.x[i][i]=1;
}
C.x[1][0]=1;
C.x[0][1]=1;
C.x[1][1]=1;
C.x[0][2]=1;
C.x[2][2]=1;
A.x[0][0]=1;
A.x[0][1]=1;
A.x[0][2]=1;
while(n){
if(n&1){
B=B*C;
}
C=C*C;
n>>=1;
}
A=A*B;
printf("%lld\n",A.x[0][2]);
}
return 0;
}
/*
*/