题目链接:BZOJ - 2326

题目分析

数据范围达到了 10^18 ,显然需要矩阵乘法了!

可以发现,向数字尾部添加一个数字 x 的过程就是 Num = Num * 10^k + x 。其中 k 是 x 的位数。

那么位数相同的数字用矩阵乘法处理就可以了。

[Num, x, 1] * [10^k, 0, 0] = [Num*10^k+x, x+1, 1]

[      1, 0, 0]

[      0, 1, 1]

枚举位数,做多次矩阵乘法。

其中两个整数相乘可能会爆 LL ,那么就用类似快速幂的慢速乘。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std; typedef long long LL; LL n, Mod; struct Matrix
{
int x, y;
LL A[5][5];
void Clear() {
memset(A, 0, sizeof(A));
}
void SetXY(int a, int b) {
x = a; y = b;
}
} M0, M_Ans, M_t; LL MulNum(LL a, LL b) {
LL f = a, ret = 0;
while (b) {
if (b & 1) {
ret += f;
if (ret > Mod) ret %= Mod;
}
b >>= 1;
f <<= 1;
if (f > Mod) f %= Mod;
}
return ret;
} Matrix Mul(Matrix Ma, Matrix Mb) {
Matrix ret;
ret.SetXY(Ma.x, Mb.y);
ret.Clear();
for (int i = 1; i <= ret.x; ++i) {
for (int j = 1; j <= ret.y; ++j) {
for (int k = 1; k <= Ma.y; ++k) {
ret.A[i][j] += MulNum(Ma.A[i][k], Mb.A[k][j]);
ret.A[i][j] %= Mod;
}
}
}
return ret;
} Matrix Pow(Matrix Ma, LL b) {
Matrix f, ret;
f = Ma;
ret.SetXY(Ma.x, Ma.y);
ret.Clear();
for (int i = 1; i <= ret.x; ++i) ret.A[i][i] = 1;
while (b) {
if (b & 1) ret = Mul(ret, f);
b >>= 1;
f = Mul(f, f);
}
return ret;
} int main()
{
scanf("%lld%lld", &n, &Mod);
LL Temp, Ans;
M0.SetXY(1, 3);
M0.Clear();
M0.A[1][1] = 0; M0.A[1][2] = 1; M0.A[1][3] = 1;
M_t.SetXY(3, 3);
Temp = 1;
for (int i = 1; i <= 18; ++i) {
Temp *= 10ll;
if (Temp > n) break;
M_t.Clear();
M_t.A[1][1] = Temp;
M_t.A[2][1] = M_t.A[2][2] = M_t.A[3][2] = M_t.A[3][3] = 1;
M_t = Pow(M_t, Temp - Temp / 10);
M0 = Mul(M0, M_t);
}
M_t.Clear();
M_t.A[1][1] = Temp;
M_t.A[2][1] = M_t.A[2][2] = M_t.A[3][2] = M_t.A[3][3] = 1;
M_t = Pow(M_t, n - Temp / 10 + 1);
M0 = Mul(M0, M_t);
Ans = M0.A[1][1];
printf("%lld\n", Ans);
return 0;
}

  

[BZOJ 2326] [HNOI2011] 数学作业 【矩阵乘法】的更多相关文章

  1. BZOJ 2326: [HNOI2011]数学作业(矩阵乘法)

    传送门 解题思路 NOIp前看到的一道题,当时想了很久没想出来,NOIp后拿出来看竟然想出来了.注意到有递推\(f[i]=f[i-1]*poww[i]+i\),\(f[i]\)表示\(1-i\)连接起 ...

  2. BZOJ 2326: [HNOI2011]数学作业( 矩阵快速幂 )

    BZOJ先剧透了是矩阵乘法...这道题显然可以f(x) = f(x-1)*10t+x ,其中t表示x有多少位. 这个递推式可以变成这样的矩阵...(不会用公式编辑器...), 我们把位数相同的一起处理 ...

  3. bzoj 2326: [HNOI2011]数学作业【dp+矩阵快速幂】

    矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式, ...

  4. bzoj 2326: [HNOI2011]数学作业

    #include<cstdio> #include<iostream> #include<cstring> #include<cmath> #defin ...

  5. [BZOJ2326] [HNOI2011] 数学作业 (矩阵乘法)

    Description Input Output Sample Input Sample Output HINT Source Solution 递推式长这样:$f[n]=f[n-1]*10^k+n$ ...

  6. 【bzoj2326】[HNOI2011]数学作业 矩阵乘法

    题目描述 题解 矩阵乘法 考虑把相同位数的数放到一起处理: 设有$k$位的数为$[l,r]$,那么枚举从大到小的第$i$个数(即枚举$r-i+1$),考虑其对$Concatenate(l..r)$的贡 ...

  7. BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘

    2326: [HNOI2011]数学作业 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1564 Solved: 910 [Submit][Statu ...

  8. [HNOI2011]数学作业 --- 矩阵优化

    [HNOI2011]数学作业 题目描述: 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M ,要求计算\(Concatenate(1..N)\; Mod\; ...

  9. 【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]

    数学作业 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Input 输入文件只有一行为用空 ...

随机推荐

  1. (C#)与Windows用户账户信息的获取

    Console.WriteLine(Environment.UserName); //计算机NetBIOS名称 Console.WriteLine(Environment.MachineName); ...

  2. cocos2d-x创建的九宫图变白块

    用UIImageView 创建的九宫图变白,直接用CCScale9Sprite创建的也是变白,找了半天原来是自己为了调整UI方便,开启了CCSprite边缘画线导致的,在ccConfig.h下 宏CC ...

  3. android 56

    ##其他布局 * LinearLayout * RelativeLayout * FrameLayout * AbsoluteLayout (绝对布局, 文档说过时,应用场景机顶盒开发,定制的平板) ...

  4. cflow察看工程函数调用关系+Linux 0.11 内核实验环境

    http://savannah.gnu.org/projects/cflow http://tinylab.org/linux-0.11-lab/ http://ftp.gnu.org/gnu/cfl ...

  5. Linux之TCPIP内核参数优化

    /proc/sys/net目录 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这 ...

  6. MySQL快捷键

    \c  clear  放弃正在输入的命令\h  help   显示一份命令清单\q   exit  或  quit  退出Mysql程序         在linux里面可以使用Ctr+D快捷键\s  ...

  7. Java基础知识强化之集合框架笔记20:数据结构之 栈 和 队列

    1.  栈 先进后出 解析图: 2. 队列 先进先出 解析图:

  8. json 序列化的两种方式

    JavaScriptSerializer Serializer = new JavaScriptSerializer(); ResultData<EUserData> resultMode ...

  9. js分家效应

    (原创文章,转载请注明出处) 有继承,那么就有分家.让我们看以下例子. var parents = function(){ } parents.prototype.money = 200; var c ...

  10. 遍历id,根据id作为条件循环查询。

    string id = "OE09924008161405102,OE36765709071405102,OE87852044171405102,OE09924008161405102&qu ...