题意:

有一个\(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. MySQL 如何在一个语句中更新一个数值后返回该值 -- 自增长种子竞态问题处理

    什么是竞态问题? 假设有一个计数器,首先当前值自增长,然后获取到自增长之后的当前值.自增长后的值有可能被有些操作用来当做唯一性标识,因此并发的操作不能允许取得相同的值. 为什么不能使用使用UPDATE ...

  2. 【转】pom.xml讲解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  3. es6+字符串string的新增方法函数

    String.includes("xxx")   返回true/false     [es5的字符串查找方法:String.indexOf() ] String.startsWit ...

  4. Countup.js:vue-countup-v2(npm)数字滚动插件

    1.官方地址:http://inorganik.github.io/countUp.js/ 2.官方demo: 3.参数说明: params——start(开始数字).end(结束数字).decima ...

  5. 【Python图像特征的音乐序列生成】关于图像特征的描述词

    查阅了很久的资料,决定依据Yoshida的<Image retrieval system using impression words>这篇论文里的词语来定义. Yoshida 等的 Ar ...

  6. RYU的GUI安装

    1. RYU安装 Ubuntu14.04 LTS 1.sudo apt-get install git python-pip libxml2-dev libxslt1-dev python2.7-de ...

  7. 交叉熵cross entropy和相对熵(kl散度)

    交叉熵可在神经网络(机器学习)中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量真实分布p与当前训练得到的概率分布q有多么大的差异. 相对熵(relativ ...

  8. python_98_面向对象_学校

    class School(object):#以后都加object(基类) def __init__(self, name, addr): self.name = name self.addr = ad ...

  9. QT+event() + 事件过滤器

    其存在的意义: mywidget.h: #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> namespace Ui { cl ...

  10. sort 与 sorted 区别:

    sort 与 sorted 区别: sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作. list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值, ...