[CODEVS 1281] Xn数列

描述

给你6个数,m, a, c, x0, n, g

Xn+1 = ( aXn + c ) mod m,求Xn

http://codevs.cn/problem/1281/


分析

比较裸的矩阵乘法题, 好久没做了, 写写思路

假设矩阵 A = { {a1, a2}, {a3, a4} }, B = { {b1, b2}, {b3, b4} }.

根据矩阵乘法的计算方法, 有 :

A×B = { {a1b1+a2b2, a1b2+a2b4}, {a3b1+a4b3, a3b2+a4b4} }.

那么我们想得到的是 a*Xn + c = Xn+1

假设 X 存在a1里, 那么应有 Xn * b1 + a2 * b2 = Xn+1

那么就可以得到 a2 = 1, b1 = a, b2 = c.

(为什么不能 a2 = c, b2 = 1 ? 因为乘完一次 a2 就变了, 下个加的就不是 c 了).

这样矩阵就建好了, 接下来就是按部就班的矩阵乘法了.

不过, 这里数据太大, 不使用特殊技巧用 unsigned long long 都会溢出. 高精度 ? 其实不用, 因为最后都要模一下.

特殊技巧

用类似快速幂的方法写一个快速加, 加一下模一下, 用来避免直接乘的溢出.


代码

20ms 256kB

额… 难道 mod 和 sum 都是保留字 ? 为啥都有高亮 ?

#include<cstdio>
using namespace std;
typedef long long LL;

LL mod, a, c, x0, n, g;

struct Matrix {
    LL m[2][2];
} base, X0;

// return a * b
LL quickadd(LL a, LL b) {
    LL ans = 0;
    a %= mod; b %= mod;
    while(b > 0) {
        if(b & 1) ans = (ans + a) % mod;
        a = (a + a) % mod;
        b >>= 1;
    }
    return ans;
}

Matrix mul(Matrix a, Matrix b) {
    Matrix ans;
    for(int i = 0; i < 2; i++)
        for(int j = 0; j < 2; j++) {
            LL sum = 0;
            for(int k = 0; k < 2; k++)
                sum = (sum + quickadd(a.m[i][k], b.m[k][j])) % mod;
            ans.m[i][j] = sum;
        }
    return ans;
}

Matrix pow(Matrix a, LL n) {
    Matrix p = {{1, 0, 0, 1}};
    while(n > 0) {
        if(n & 1) p = mul(p, a);
        a = mul(a, a);
        n /= 2;
    }
    return p;
}

int main() {
    scanf("%lld%lld%lld%lld%lld%lld", &mod, &a, &c, &x0, &n, &g);
    base = (Matrix) {{a, 0, 1, 1}};
    X0 = (Matrix){{x0, c, 0, 0}};
    Matrix ans = mul(X0, pow(base, n));
    printf("%lld\n", ans.m[0][0] % g);
    return 0;
}
时间: 2024-10-10 14:16:58

[CODEVS 1281] Xn数列的相关文章

codevs 1281 Xn数列 (矩阵乘法)

/* 再来个题练练手 scanf longlong 有bug....... */ #include<cstdio> #include<iostream> #include<cstring> #define ll long long using namespace std; ll n,m,x,y,x0,g; ll f[3][3],a[3][3]; ll slow_mul(ll a,ll b,ll c) { ll ans=0; a=a%c;b=b%c; while(b) {

【CODEVS】1281 Xn数列

[算法]矩阵快速幂 [题解]T*A(n-1)=A(n)矩阵如下: a 1 * x(n-1) 0 = xn 0 0 1    c        0    c   0 防止溢出可以用类似快速幂的快速乘. #include<cstdio> #include<algorithm> #define ll long long using namespace std; ll MOD,A,c,x0,n,g,a[2][2],b[2][2],t[2][2]; ll mull(ll x,ll y) {

【WikiOI "天梯"1281】 Xn数列

题目描述Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 输入描述Input Description 一行六个数 m, a, c, x0, n, g 输出描述Output Description 输出一个数 Xn mod g 样例输入Sample Input 11 8 7 1 5 3 样例输出Sample Output 2 数据范围及提示Data Size & H

C++之路进阶——矩阵乘法(Xn数列)

1281 Xn数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 输入描述 Input Description 一行六个数 m, a, c, x0, n, g 输出描述 Output Description 输出一个数 Xn mod g 样例输入 Sample Inpu

矩阵乘法快速幂 codevs 1250 Fibonacci数列

codevs 1250 Fibonacci数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 定义:f0=f1=1, fn=fn-1+fn-2(n>=2).{fi}称为Fibonacci数列. 输入n,求fn mod q.其中1<=q<=30000. 输入描述 Input Description 第一行一个数T(1<=T<=10000). 以下T行,每行两个数,n,q(n<=109, 1<

Xn数列(codevs 1281)

题目描述 Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 输入描述 Input Description 一行六个数 m, a, c, x0, n, g 输出描述 Output Description 输出一个数 Xn mod g 样例输入 Sample Input 11 8 7 1 5 3 样例输出 Sample Output 2 /* 这个题显然用矩阵乘法,公式也

【CODEVS1281】Xn数列

Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 Input 一行六个数 m, a, c, x0, n, g Output 输出一个数 Xn mod g Sample Input 11 8 7 1 5 3 Sample Output 2 HINT int64按位相乘可以不要用高精度. 题解 对于取模运算进行一个修改,将乘法修改为倍增乘法(类似于快速幂): long l

Codevs 4357 不等数列

不等数列 [题目描述] 将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入“>”和“<”.问在所有排列中,有多少个排列恰好有k个“<”.答案对2012取模. [输入格式] 第一行2个整数n,k. [输出格式] 一个整数表示答案. [样例输入] 5 2 [样例输出] 66 [数据范围] 对于30%的数据:n <= 10 对于100%的数据:k < n <= 1000, 对于30% n<=10的数据,搜索打表,状态压缩动态规划...... 对于1--n等

codevs 2947 饥饿数列

题目描述 Description Iahub和Iahubina去一家豪华餐厅约会,然而到了付账时,收银员不向他们收取餐费,而是要求他们写出一个数列.对这个数列的要求如下: 1.数列的长度为n 2.对于数列中的任意两个满足i<j的数ai.aj,要求ai<aj. 3.对于数列中的任意两个满足i<j的数ai.aj,要求ai不能整除aj. 输入描述 Input Description 一个数n 输出描述 Output Description 一行,n个数,所求数列. 如果有多种可行数列,输出字典