codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数

  对于这道题目以及我的快速幂以及我的一节半晚自习我表示无力吐槽,,

  首先矩阵乘法和快速幂没必要太多说吧,,嗯没必要,,我相信没必要,,实在做不出来写两个矩阵手推一下也就能理解矩阵的顺序了,要格外注意一些细节,比如快速幂时ans矩阵的初始化方式,快速幂的次数,矩阵乘法过程中对临时矩阵的清零,最后输出结果时的初始矩阵。。。矩阵快速幂好理解但是细节还是有点小坑的。。

  下面就是满满的槽点,,高能慎入!!!

 



  对于这个题目要求矩阵过程中对m取模,结果对g取模,我表示难以接受,,上来没看清题直接wa19个点,另,经本人实测,在矩阵中直接对m和g取模会直接挂掉,

  历经千辛万苦终于改对之后,,发现wa了3个点,,经过eirlys(某坑货)的提示发现过程中乘法会爆long long,于是便一脸mb,脑抽的改成unsign long long后依旧过不了,认真的去看了题解,,然后整个人就呵呵哒了,,题解告诉我要手写快速乘法。。。。。。

  真是够了。。。。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4
 5
 6 struct data {
 7     long long f[3][3];
 8     data (void) {
 9         memset(f, 0, sizeof(f));
10         f[0][0] = 1;
11         f[1][1] = 1;
12         f[2][2] = 1;
13     }
14     void clear(void) {
15         memset(f, 0, sizeof(f));
16     }
17     void print(void) {
18         for (int i = 0; i < 3; i++) {
19             for (int j = 0; j < 3; j++) printf("%lld ", f[i][j]);
20             printf("\n");
21         }
22         printf("\n");
23     }
24 };
25
26 long long m, a, c, x0, n, g;
27 data cur;
28
29 long long mu (long long a1, long long a2) {
30     long long ans = 0;
31     while (a2 > 0) {
32         if (a2 & 1) ans = (ans + a1) % m;
33         a1 = (a1 + a1) % m;
34         a2 >>= 1;
35     }
36     return (ans);
37 }
38
39 data operator * (data a1, data a2) {
40     data t;
41     t.clear();
42     for (int i = 0; i < 3; i++)
43         for (int j = 0; j < 3; j++)
44             for (int k = 0; k < 3; k++) {
45                 t.f[i][j] = (t.f[i][j] + mu(a1.f[i][k], a2.f[k][j]) % m) % m;
46             }
47     return (t);
48 }
49
50 data qpow(data x, long long v) {
51     data ans;
52     while (v > 0) {
53         if (v & 1) ans = ans * x;
54         x = x * x;
55         v >>= 1;
56     }
57     return (ans);
58 }
59
60 int main () {
61     scanf("%lld %lld %lld %lld %lld %lld", &m, &a, &c, &x0, &n, &g);
62     cur.clear();
63     cur.f[1][0] = 1;
64     cur.f[1][1] = a % m;
65     cur.f[2][1] = 1;
66     cur.f[2][2] = 1;
67     cur = qpow(cur, n);
68     //cur.print();
69     long long ans = (mu(x0,cur.f[1][1]) % m + mu(c, cur.f[2][1] % m)) % m;
70     ans = ((ans % g) + g) % g;
71     printf("%lld", ans);
72     return 0;
73 }
时间: 2024-10-16 14:15:56

codevs1281 矩阵乘法 快速幂 !!!手写乘法取模!!! 练习struct的构造函数和成员函数的相关文章

CodeForces 450B (矩阵快速幂模板题+负数取模)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=51919 题目大意:斐波那契数列推导.给定前f1,f2,推出指定第N项.注意负数取模的方式:-1%(10^9+7)=10^9+6. 解题思路: 首先解出快速幂矩阵.以f3为例. [f2]  * [1 -1] = [f2-f1]=[f3]  (幂1次) [f1]  * [1  0]     [f2]      [f2] 于是fn=[f2] *[1 -1]^(n-2)

快速求斐波那契数列(矩阵乘法+快速幂)

斐波那契数列 给你一个n:f(n)=f(n-1)+f(n-2) 请求出 f(f(n)),由于结果很大请 对答案 mod 10^9+7; 1<=n<=10^100; 用矩阵乘法+快速幂求斐波那契数列是经典应用: 矩阵公式 C i j=C i k *C k j; 根据递推式 构造2*2矩阵: 原始矩阵 1 0 0 1 矩阵 2 1 1 1 0 原始矩阵与矩阵 2相乘达到转化状态效果: 对矩阵二进行快速幂 乘法:达到快速转化矩阵的效果: 即使达到快速转化状态:那么大的数据范围也很难求解: 高精?这有

乘方快速幂 OR 乘法快速幂

关于快速幂这个算法,已经不想多说,很早也就会了这个算法,但是原来一直靠着模板云里雾里的,最近重新学习,发现忽视了一个重要的问题,就是若取模的数大于int型,即若为__int64的时候应该怎么办,这样就得用到乘法快速幂+乘方快速幂了. 快速幂一般是为了解决乘方取模问题的,显然思想就是二分,下面贴上快速幂模板: 1 __int64 mulpow(__int64 a,__int64 p,__int64 m) 2 { 3 __int64 ans = 1; 4 while(p) 5 { 6 if(p&1)

Poj 3233 Matrix Power Series(矩阵二分快速幂)

题目链接:http://poj.org/problem?id=3233 解题报告:输入一个边长为n的矩阵A,然后输入一个k,要你求A + A^2 + A^3 + A^4 + A^5.......A^k,然后结果的每个元素A[i][j] % m.(n <= 30,k < 10^9,m < 10^4) 要用到矩阵快速幂,但我认为最重要的其实还是相加的那个过程,因为k的范围是10^9,一个一个加肯定是不行的,我想了一个办法就是我以k = 8为例说明: ans = A + A^2 + A^3 +

矩阵乘法快速幂 codevs 1732 Fibonacci数列 2

1732 Fibonacci数列 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值.但是1250中,n<=109.现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000 输入描述 Input Description 输入有多组数据,每

【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂

题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj (1<=j<=k)是给定的自然数.写一个程序,给定自然数m <= n, 计算am + am+1 + am+2 + ... + an, 并输出它除以给定自然数p的余数的值. 输入 由四行组成. 第一行是一个自然数k. 第二行包含k个自然数b1, b2,...,bk. 第三行包含k个自然数c1,

【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2745  Solved: 1694[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..

C++-POJ3735-Training little cats[矩阵乘法][快速幂]

矩阵快速幂,主要是考构造.另外,swap总是写龊? 为什么?干脆放弃了.唉,我太难了. 思路:操作e和s都很好想,主要是g操作 我们可以额外空出一位,记为1,每次要加1,就对这个额外的1进行计算即可 不妨定义A=[1 0 0 ... 0],此时只要构造一组操作的等效矩阵T就好了 就是添一位使初始矩阵A变为一个n+1元组,编号为0到n.以三只猫为例[1 0 0 0] 1 #include <cstdio> 2 typedef long long ll; 3 const int N=105; 4

【BZOJ 2323】 2323: [ZJOI2011]细胞 (DP+矩阵乘法+快速幂*)

2323: [ZJOI2011]细胞 Description 2222年,人类在银河系外的某颗星球上发现了生命,并且携带了一个细胞回到了地球.经过反复研究,人类已经完全掌握了这类细胞的发展规律: 这种细胞最初的形态是"长条形",一端是头,一端是尾,中间是躯干.细胞内部含有一列密码(你可以认为它是这种细胞的DNA).密码是一个长度为n的数字串,且仅含有1~9这9种数字,沿着细胞的躯干从头到尾排列着. 首先,细胞会经历一次分裂.细胞将沿躯干方向分裂成若干个球体,躯干将退化成丝状物,连接着相