您的位置:首页 > 其它

BZOJ3329 Xorequ(数位dp+矩阵快速幂)

2018-09-21 18:22 162 查看

  显然当x中没有相邻的1时该式成立,看起来这也是必要的。

  于是对于第一问,数位dp即可。第二问写出dp式子后发现就是斐波拉契数列,矩阵快速幂即可。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define P 1000000007
#define ll long long
int T,num[100];
ll n,dp[100][2][2];
struct matrix
{
int n,a[2][2];
matrix operator *(const matrix&b) const
{
matrix c;c.n=n;memset(c.a,0,sizeof(c.a));
for (register int i=0;i<n;i++)
for (register int j=0;j<2;j++)
for (register int k=0;k<2;k++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j]%P)%P;
return c;
}
}f,a;
ll solve1(ll n)
{
memset(dp,0,sizeof(dp));
int m=-1;
while (n) num[++m]=n&1,n>>=1;
dp[m+1][0][1]=1;
for (int i=m;~i;i--)
if (num[i])
{
dp[i][0][0]=dp[i+1][0][0]+dp[i+1][0][1]+dp[i+1][1][0]+dp[i+1][1][1];
dp[i][1][0]=dp[i+1][0][0];
dp[i][1][1]=dp[i+1][0][1];
}
else
{
dp[i][0][0]=dp[i+1][0][0]+dp[i+1][1][0];
dp[i][0][1]=dp[i+1][0][1]+dp[i+1][1][1];
dp[i][1][0]=dp[i+1][0][0];
}
return dp[0][0][0]+dp[0][0][1]+dp[0][1][0]+dp[0][1][1];
}
int solve2(ll n)
{
a.n=2;a.a[0][0]=0;a.a[0][1]=a.a[1][0]=a.a[1][1]=1;
f.n=1;f.a[0][0]=0,f.a[0][1]=1;
for (;n;n>>=1,a=a*a) if (n&1) f=f*a;
return f.a[0][1];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3329.in","r",stdin);
freopen("bzoj3329.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
scanf(LL,&n);
printf(LL,solve1(n)-1);
printf("%d\n",solve2(n+1));
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: