纪念SlingShot FZU - 1683
2017-11-20 15:10
399 查看
点击打开链接
推出公式就好办了 直接上图吧。。
还有 题目要求前(n+1)项的和 要用到二分 详见代码
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define M 2009
int gg[4][4],mat[4][4],ans[4][4],pre[4][4];
int n;
void init()
{
gg[1][1]=115,gg[1][2]=28,gg[1][3]=5;
gg[2][1]=28,gg[2][2]=5,gg[2][3]=3;
gg[3][1]=5,gg[3][2]=3,gg[3][3]=1;
mat[1][1]=3,mat[1][2]=1,mat[1][3]=0;
mat[2][1]=2,mat[2][2]=0,mat[2][3]=1;
mat[3][1]=7,mat[3][2]=0,mat[3][3]=0;
return;
}
void add(int a[][4],int b[][4],int c[][4])
{
int t[4][4];
int i,j;
memset(t,0,sizeof(t));
for(i=1;i<=3;i++)
{
for(j=1;j<=3;j++)
{
t[i][j]=(a[i][j]%M+b[i][j]%M)%M;
}
}
memcpy(c,t,sizeof(t));
return;
}
void mul(int a[][4],int b[][4],int c[][4])
{
int t[4][4];
int i,j,k;
memset(t,0,sizeof(t));
for(i=1;i<=3;i++)
{
for(j=1;j<=3;j++)
{
t[i][j]=0;
for(k=1;k<=3;k++)
{
t[i][j]+=((a[i][k]%M)*(b[k][j])%M)%M;
t[i][j]%=M;
}
}
}
memcpy(c,t,sizeof(t));
return;
}
void bin(int cur)
{
int tem1[4][4],tem2[4][4];
if(cur==1)
{
memcpy(ans,mat,sizeof(mat));
memcpy(pre,mat,sizeof(mat));
return;
}
bin(cur/2);
if(cur%2==0)
{
mul(ans,pre,tem1);
add(ans,tem1,ans);
mul(pre,pre,pre);
}
if(cur%2==1)
{
mul(pre,mat,tem2);
mul(ans,tem2,tem1);
add(ans,tem1,ans);
add(ans,tem2,ans);
mul(pre,pre,pre);
mul(pre,mat,pre);
}
return;
}
int main()
{
int t,cas,i,j;
init();
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
if(n==0)
{
printf("Case %d: 1\n",cas);
}
else if(n==1)
{
printf("Case %d: 4\n",cas);
}
else if(n==2)
{
printf("Case %d: 9\n",cas);
}
else if(n==3)
{
printf("Case %d: 37\n",cas);
}
else if(n==4)
{
printf("Case %d: 152\n",cas);
}
else
{
n-=4;
bin(n);
mul(gg,ans,ans);
printf("Case %d: %d\n",cas,(152+ans[1][1])%2009);
}
}
return 0;
}
推出公式就好办了 直接上图吧。。
还有 题目要求前(n+1)项的和 要用到二分 详见代码
#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define M 2009
int gg[4][4],mat[4][4],ans[4][4],pre[4][4];
int n;
void init()
{
gg[1][1]=115,gg[1][2]=28,gg[1][3]=5;
gg[2][1]=28,gg[2][2]=5,gg[2][3]=3;
gg[3][1]=5,gg[3][2]=3,gg[3][3]=1;
mat[1][1]=3,mat[1][2]=1,mat[1][3]=0;
mat[2][1]=2,mat[2][2]=0,mat[2][3]=1;
mat[3][1]=7,mat[3][2]=0,mat[3][3]=0;
return;
}
void add(int a[][4],int b[][4],int c[][4])
{
int t[4][4];
int i,j;
memset(t,0,sizeof(t));
for(i=1;i<=3;i++)
{
for(j=1;j<=3;j++)
{
t[i][j]=(a[i][j]%M+b[i][j]%M)%M;
}
}
memcpy(c,t,sizeof(t));
return;
}
void mul(int a[][4],int b[][4],int c[][4])
{
int t[4][4];
int i,j,k;
memset(t,0,sizeof(t));
for(i=1;i<=3;i++)
{
for(j=1;j<=3;j++)
{
t[i][j]=0;
for(k=1;k<=3;k++)
{
t[i][j]+=((a[i][k]%M)*(b[k][j])%M)%M;
t[i][j]%=M;
}
}
}
memcpy(c,t,sizeof(t));
return;
}
void bin(int cur)
{
int tem1[4][4],tem2[4][4];
if(cur==1)
{
memcpy(ans,mat,sizeof(mat));
memcpy(pre,mat,sizeof(mat));
return;
}
bin(cur/2);
if(cur%2==0)
{
mul(ans,pre,tem1);
add(ans,tem1,ans);
mul(pre,pre,pre);
}
if(cur%2==1)
{
mul(pre,mat,tem2);
mul(ans,tem2,tem1);
add(ans,tem1,ans);
add(ans,tem2,ans);
mul(pre,pre,pre);
mul(pre,mat,pre);
}
return;
}
int main()
{
int t,cas,i,j;
init();
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
if(n==0)
{
printf("Case %d: 1\n",cas);
}
else if(n==1)
{
printf("Case %d: 4\n",cas);
}
else if(n==2)
{
printf("Case %d: 9\n",cas);
}
else if(n==3)
{
printf("Case %d: 37\n",cas);
}
else if(n==4)
{
printf("Case %d: 152\n",cas);
}
else
{
n-=4;
bin(n);
mul(gg,ans,ans);
printf("Case %d: %d\n",cas,(152+ans[1][1])%2009);
}
}
return 0;
}
相关文章推荐
- FZU - 1683 纪念SlingShot
- 纪念SlingShot FZU - 1683
- FZU 1683 纪念SlingShot ★(矩阵 && 求和 && 线性变换)
- FZU oj 1683 纪念SlingShot(矩阵快速幂)
- FZU 1683 纪念SlingShot ★(矩阵 && 求和 && 线性变换)
- FZU oj 1683 纪念SlingShot(矩阵快速幂)
- FZU1683---纪念SlingShot(矩阵快速幂(数据劣质))
- FZU 1683 纪念SlingShot
- FZU 1683 纪念SlingShot
- fzu 1683 纪念SlingShot 矩阵
- fzu 1683 纪念SlingShot(矩阵快速幂)
- FZU 1683 纪念SlingShot 矩阵快速幂
- FZU 1683 纪念SlingShot (简单的矩阵快速幂)
- FZU 1683 纪念SlingShot
- FZU - 1683 纪念SlingShot 矩阵快速幂
- FZU 1683 纪念SlingShot
- fzu 1683 纪念SlingShot (矩阵快速幂)
- FZU 1683 纪念SlingShot (构造矩阵)
- FZU 1683 纪念SlingShot
- FZU 1683 纪念SlingShot (构造矩阵)