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

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 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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值