bzoj 3329: Xorequ(DP+矩阵快速幂)

来源:互联网 发布:黑客帝国之矩阵革命 编辑:程序博客网 时间:2024/06/07 08:57

3329: Xorequ

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 1134  Solved: 491
[Submit][Status][Discuss]

Description

Input

第一行一个正整数,表示数据组数据 ,接下来T行
每行一个正整数N

Output

2*T行
第2*i-1行表示第i个数据中问题一的解,

第2*i行表示第i个数据中问题二的解,

Sample Input

1
1

Sample Output

1
2


第一问:

满足条件的x二进制中不存在相邻的1

所以可以直接数位DP

第二问:

按第一问打个表可以明显看出答案是斐波那契数列的第n+1项

矩阵快速幂

#include<stdio.h>#include<string.h>#define LL long long#define mod 1000000007LL 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;}