题意:

有一个\(base(2 \leq base \leq 6)\)进制系统,这里面的数都是整数,不含前导0,相邻两个数字不相同。

而且每个数字有一个得分\(score(1 \leq score \leq 10^9)\),得分为 相邻两个数字之差的平方之和。

给出\(base\)和\(score\),求满足条件的整数的个数 \(mod \, 2^{32}\)。

分析:

首先考虑DP的做法:

设\(dp(i, j)\)表示满足当前分数为\(i\)最后一个数字是\(j\)的数字的个数。

递推就是枚举下一个数字\(k\),就有转移方程:

\(dp(i+d,k)=\sum dp(i, j)\),其中\(k \neq j\)且\(d=(k-j)^2\)。

这种方法的复杂度使\(O(base^2 \cdot score)\)的。

考虑矩阵优化:

因为状态转移中,能得到的最大分数是\((base-1)^2\),所以我们的转移矩阵只要保留前面\((base-1)^2\)个\(score\)的信息就行了。

用语言不方便表达,我举具体例子,

当\(base=3\)时,有如下转移:



上面9行很好理解,就是一个错位。

下面3行才是状态的转移。

容易看出,我们的矩阵的边长最大会达到\(6(6-1)^2=150\)。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; typedef unsigned int LL;
const int maxn = 150; int n, m, sz; struct Matrix
{
LL a[maxn][maxn]; Matrix() {
for(int i = 0; i < maxn; i++)
for(int j = 0; j < maxn; j++) a[i][j] = 0;
} Matrix operator * (const Matrix& t) const {
Matrix ans;
for(int i = 0; i < sz; i++)
for(int j = 0; j < sz; j++) if(a[i][j])
for(int k = 0; k < sz; k++)
ans.a[i][k] += a[i][j] * t.a[j][k];
return ans;
}
}; Matrix pow_mod(Matrix a, int n) {
Matrix ans;
for(int i = 0; i < sz; i++) ans.a[i][i] = 1;
while(n) {
if(n & 1) ans = ans * a;
a = a * a;
n >>= 1;
}
return ans;
} LL a[maxn], dp[25][6]; int main()
{
int T; scanf("%d", &T);
for(int kase = 1; kase <= T; kase++) {
printf("Case %d: ", kase);
scanf("%d%d", &n, &m);
int N = (n - 1) * (n - 1) * n; //DP
memset(dp, 0, sizeof(dp));
for(int i = 1; i < n; i++) dp[0][i] = 1;
for(int i = 0; i < (n - 1) * (n - 1); i++) {
for(int j = 0; j < n; j++) {
for(int k = 0; k < n; k++) {
int d = (k - j) * (k - j);
if(!d || i + d > (n - 1) * (n - 1)) continue;
dp[i + d][k] += dp[i][j];
}
}
} if(m < (n - 1) * (n - 1)) {
LL ans = 0;
for(int i = 0; i < n; i++) ans += dp[m][i];
printf("%u\n", ans);
continue;
} sz = N;
int s = (n - 1) * (n - 1);
for(int i = 0; i < (n - 1) * (n - 1); i++)
for(int j = 0; j < n; j++)
a[i * n + j] = dp[i][j];
Matrix M; for(int i = n; i < N; i++) M.a[i - n][i] = 1;
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++) if(j != i) {
int d = (j - i) * (j - i);
M.a[N - n + i][n * (s - d) + j] = 1;
}
M = pow_mod(M, m - (n - 1) * (n - 1) + 1);
LL ans = 0;
for(int i = N - n; i < N; i++)
for(int j = 0; j < N; j++)
ans += M.a[i][j] * a[j];
printf("%u\n", ans);
} return 0;
}

UVa 11651 Krypton Number System DP + 矩阵快速幂的更多相关文章

  1. bnuoj 34985 Elegant String DP+矩阵快速幂

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...

  2. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  3. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  4. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  5. BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*

    BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...

  6. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  7. codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)

    题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...

  8. [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

  9. POJ-3070Fibonacci(矩阵快速幂求Fibonacci数列) uva 10689 Yet another Number Sequence【矩阵快速幂】

    典型的两道矩阵快速幂求斐波那契数列 POJ 那是 默认a=0,b=1 UVA 一般情况是 斐波那契f(n)=(n-1)次幂情况下的(ans.m[0][0] * b + ans.m[0][1] * a) ...

随机推荐

  1. 原创 html动态表格

    <table id="opttb"> <asp:Repeater ID="tempOptions" runat="server&qu ...

  2. 基于Java实现的快速排序

    简述 快速排序是一种排序执行效率很高的排序算法,它利用分治法来对待排序序列进行分治排序,它的思想主要是通过一趟排序将待排记录分隔成独立的两部分,其中的一部分比关键字小,后面一部分比关键字大,然后再对这 ...

  3. I/O————流

    流的关系图 缓冲流分为字节和字符缓冲流(图中是经常用的搭配,PrintWrite与BufferedWrite都继承java.io.Write) 字节缓冲流为: BufferedInputStream— ...

  4. ecshop分类页把分类描述改成FCKeditor编辑器

    最近放一个网站 http://www.macklin.cn/productline/35 有个产品分类页面需要添加分类缩略图和图文的描述 一.首先说下添加分类缩略图的步骤吧 1,依葫芦画瓢,参照的是e ...

  5. Webpack 入门学习

    1.什么是Webpack? Webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等 ...

  6. Android 使用RecyclerView实现多行水平分页的GridView效果和ViewPager效果

    前些天看到有人在论坛上问这种效果怎么实现,没写过也没用过这个功能,网上查了一下,大多是使用ViewPager+GridView或者HorizontalScrollView+GridView实现,不过貌 ...

  7. GitHub 开启 Two-factor authentication,如何在命令行下更新和上传代码

    最近在使用GitHub管理代码,在git命令行管理代码时候遇到一些问题. 如果开起了二次验证(Two-factor authentication两个要素认证),命令行会一直提示输入用户名和密码.查找了 ...

  8. Beginning Python Chapter 1 Notes

    James Payne(American)编写的<Beginning Python>中文译作<Python入门经典>,堪称是Python的经典著作. 当然安装Python是很简 ...

  9. window对象的几个重要方法

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>Java ...

  10. ES6中const的用法

    const声明一个只读的常量.一旦声明,常量的值就不能改变.且const一旦声明变量,就必须立即初始化,不能留到以后赋值. const的作用域与let命令相同:只在声明所在的块级作用域内有效. con ...