您的位置:首页 > 运维架构

CodeForces 551 D.GukiZ and Binary Operations(dp+矩阵快速幂)

2017-08-08 10:36 501 查看
Description



Input

四个整数n,k,l,m (2<=n<=1e18,0<=k<=1e18,0<=l<=64,1<=m<=1e9+7)

Output

输出满足条件的序列a个数,结果模m

Sample Input

2 1 2 10

Sample Output

3

Solution



Code

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
struct Mat
{
int mat[3][3];//矩阵
int row,col;//矩阵行列数
};
Mat mod_mul(Mat a,Mat b,int p)//矩阵乘法
{
Mat ans;
ans.row=a.row;
ans.col=b.col;
memset(ans.mat,0,sizeof(ans.mat));
for(int i=0;i<ans.row;i++)
for(int k=0;k<a.col;k++)
if(a.mat[i][k])
for(int j=0;j<ans.col;j++)
ans.mat[i][j]=(ans.mat[i][j]+(ll)a.mat[i][k]*b.mat[k][j])%p;
return ans;
}
Mat mod_pow(Mat a,ll k,int p)//矩阵快速幂
{
Mat ans;
ans.row=a.row;
ans.col=a.col;
for(int i=0;i<a.row;i++)
for(int j=0;j<a.col;j++)
ans.mat[i][j]=(i==j);
while(k)
{
if(k&1)ans=mod_mul(ans,a,p);
a=mod_mul(a,a,p);
k>>=1;
}
return ans;
}
int inc(int a,int b,int m)
{
return a+b>=m?a+b-m:a+b;
}
int dec(int a,int b,int m)
{
return a-b<0?a-b+m:a-b;
}
int Pow(int a,ll b,int p)
{
int ans=1;
while(b)
{
if(b&1)ans=(ll)ans*a%p;
a=(ll)a*a%p;
b>>=1;
}
return ans;
}
int l,m;
ll n,k;
Mat A;
int main()
{
A.row=A.col=2;
A.mat[0][0]=A.mat[0][1]=A.mat[1][0]=1,A.mat[1][1]=0;
while(~scanf("%I64d%I64d%d%d",&n,&k,&l,&m))
{
int res=0,num0=0,num1=0;
while(k)
{
res++;
if(k&1)num1++;
k/=2;
}
num0=l-num1;
if(res>l)printf("0\n");
else
{
Mat B=mod_pow(A,n,m);
int ans1=(B.mat[0][0]+B.mat[0][1])%m;
int ans2=dec(Pow(2,n,m),ans1,m);
int ans=(ll)Pow(ans1,num0,m)*Pow(ans2,num1,m)%m;
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: