第一行一个正整数,表示数据组数据 ,接下来T行
每行一个正整数N
2*T行
第2*i-1行表示第i个数据中问题一的解,
第2*i行表示第i个数据中问题二的解,
第一问:
满足条件的x二进制中不存在相邻的1
所以可以直接数位DP
第二问:
按第一问打个表可以明显看出答案是斐波那契数列的第n+1项
矩阵快速幂
#include
#include
#define LL long long
#define mod 1000000007
LL dp[80][2], a[80];
typedef struct
{
LL a[4][4];
void init()
{
memset(a, 0, sizeof(a));
a[1][1] = a[1][2] = a[2][1] = 1;
}
void unit()
{
memset(a, 0, sizeof(a));
a[1][1] = a[2][2] = 1;
}
}Matrix;
Matrix Jjcf(Matrix p1, Matrix p2) /*矩阵乘法*/
{
Matrix pe;
LL i, j, k;
memset(pe.a, 0, sizeof(pe.a));
for(i=1;i<=2;i++)
{
for(j=1;j<=2;j++)
{
for(k=1;k<=2;k++)
pe.a[i][j] = (pe.a[i][j]+p1.a[i][k]*p2.a[k][j])%mod;
}
}
return pe;
}
Matrix Powto(Matrix p, LL k)
{
Matrix bg, E;
E.unit();
if(k==0)
return E;
if(k==1)
return p;
bg = Powto(p, k>>1);
bg = Jjcf(bg, bg);
if((k&1)==1)
bg = Jjcf(bg, p);
return bg;
}
int main(void)
{
Matrix Jz;
LL T, n, i, temp, ans;
dp[0][1] = dp[0][0] = 1;
for(i=1;i<=62;i++)
{
dp[i][0] = dp[i-1][1]+dp[i-1][0];
dp[i][1] = dp[i-1][0];
}
scanf("%lld", &T);
while(T--)
{
scanf("%lld", &n);
temp = n+1;
for(i=0;i<=62;i++)
{
a[i] = temp%2;
temp /= 2;
}
temp = ans = 0;
for(i=62;a[i]==0;i--);
for(;i>=0;i--)
{
if(a[i]==1 && temp==0)
ans += dp[i][0];
if(a[i]==1 && a[i+1]==1)
temp = 1;
}
printf("%lld\n", ans-1);
Jz.init();
Jz = Powto(Jz, n+1);
printf("%lld\n", Jz.a[1][1]);
}
return 0;
}