标签:emc 矩阵快速幂 base pac sign 初始 pre scan sys
原题链接
考察:矩阵快速幂+线性dp
思路:
??这个dp定义完全不敢往那方面想(),定义f[i][j]为分数为i,最后一位为j的方案数.
??要说的事只有一个:谨慎防止数组越界
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 10,M = 155;
int base,score;
unsigned int dp[M][N],f[M],a[M][M];
void init()
{
memset(dp,0,sizeof dp);
memset(a,0,sizeof a);
memset(f,0,sizeof f);
for(int i=1;i<base;i++) dp[0][i] = 1;
for(int i=1;i<(base-1)*(base-1);i++)
for(int j=0;j<base;j++)
for(int k=0;k<base;k++)
{
int d= (j-k)*(j-k);
if(i-d<0||!d) continue;//细节过多
dp[i][j]+=dp[i-d][k];
}
for(int i=0;i<(base-1)*(base-1);i++)
for(int j=0;j<base;j++)
f[i*base+j] = dp[i][j];
int up = (base-1)*(base-1)*base;
for(int i=base;i<up;i++)
a[i][i-base] = 1;
int p = (base-1)*(base-1);
for(int k=0;k<base;k++)
for(int j=0;j<base;j++)
{//神优化 的初始化= =
if(k==j) continue;
int d = (k-j)*(k-j);
a[(p-d)*base+j][up-base+k] = 1;
}
}
void mul(unsigned int f[],unsigned int a[][M])
{
unsigned int res[M];
memset(res,0,sizeof res);
int Maxn = (base-1)*(base-1)*base;
for(int i=0;i<Maxn;i++)
for(int j=0;j<Maxn;j++)
res[i] = (res[i]+(LL)f[j]*a[j][i]);
memcpy(f,res,sizeof res);
}
void mul(unsigned int a[][M])
{
unsigned int res[M][M];
memset(res,0,sizeof res);
int Maxn = (base-1)*(base-1)*base;
for(int i=0;i<Maxn;i++)
for(int j=0;j<Maxn;j++)
for(int k=0;k<Maxn;k++)
res[i][j] = (res[i][j]+(LL)a[i][k]*a[k][j]);
memcpy(a,res,sizeof res);
}
int main()
{
int T,kcase = 0;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&base,&score);
init();
unsigned int ans = 0;
if(score<(base-1)*(base-1))
{
for(int i=0;i<base;i++)
ans+=dp[score][i];
printf("Case %d: %u\n", ++kcase,ans);
continue;
}
score-=(base-1)*(base-1)-1;
while(score)
{
if(score&1) mul(f,a);
mul(a);
score>>=1;
}
int up = (base-1)*(base-1)-1;
for(int i=0;i<base;i++)
ans+=f[up*base+i];
printf("Case %d: %u\n",++kcase,ans);
}
return 0;
}
Krypton Number System UVA - 11651
标签:emc 矩阵快速幂 base pac sign 初始 pre scan sys
原文地址:https://www.cnblogs.com/newblg/p/14861081.html