HDU4565-So Easy!(共轭运用+矩阵快速幂)

题目链接

题意:

求解 

思路:

记(a+b√)n为An,配项

Cn=An+Bn=(a+b√)n+(a?b√)n

两项恰好共轭,所以Cn是整数。又根据限制条件

(a?1)2<b<a2?0<a?b√<1?0<(a?b√)n<1?Bn<1

也就是说Cn=?An?

Sn=(Cn)%m

求Cn的方法是递推。
对Cn乘以(a+b√)+(a?b√)

于是

Cn+1=2aCn?(a2?b)Cn?1

把这个递推式写成矩阵形式

[Cn+1Cn]=[2a1?(a2?b)0][CnCn?1]

于是就可以用矩阵快速幂来做了

[Cn+1Cn]=[2a1?(a2?b)0]n[C1C0]

公式推倒链接

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;
//typedef __int64 ll;

ll a, b, n, m;

struct mat{
    ll s[2][2];
    mat() {
        memset(s, 0, sizeof(s));
    }
    mat operator * (const mat& c) {
        mat ans;
        memset(ans.s, 0, sizeof(ans.s));
        for (int i = 0; i < 2; i++)
            for (int j = 0; j < 2; j++)
                ans.s[i][j] = (s[i][0] * c.s[0][j] + s[i][1] * c.s[1][j]) % m;
        return ans;
    }
    void put() {
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++)
                printf("%lld ", s[i][j]);
            printf("\n");
        }
    }
}c;

void init() {
    c.s[0][0] = 2 * a;
    c.s[0][1] = b - a * a;
    c.s[1][0] = 1;
    c.s[1][1] = 0;
}

mat pow_mod(ll k) {
    if (k == 1)
        return c;
    mat a = pow_mod(k / 2);
    mat ans = a * a;
    if (k % 2)
        ans = ans * c;
    return ans;
}

int main() {
    while (scanf("%lld%lld%lld%lld", &a, &b, &n, &m) != EOF) {
        init();
        ll s1, s2;
        s1 = (a * 2) % m;
        double t = pow(a + sqrt((double)b), 2);
        s2 = (ll)ceil(t) % m;
        if (n == 1)
            printf("%lld\n", s1);
        else if (n == 2)
            printf("%lld\n", s2);
        else {
            mat ans = pow_mod(n - 2);
            ll a = (((ans.s[0][0] * s2 % m ) + m) % m + ((ans.s[0][1] * s1 % m ) + m)% m);
            printf("%lld\n", a % m);
        }
    }
    return 0;
}
时间: 2024-08-06 03:47:10

HDU4565-So Easy!(共轭运用+矩阵快速幂)的相关文章

hdu 4565 So Easy! (共轭构造+矩阵快速幂)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4565 题目大意: 给出a,b,n,m,求出的值, 解题思路: 因为题目中出现了开根号,和向上取整后求余,所以用矩阵快速幂加速求解过程的时候,会产生误差,就很自然地想到了凑数,因为(a-1)^2<b<a^2,得出0<a-sqrt(b)<1,则无论n取多大,(a-sqrt(b))^n都是小于1的,(a-sqrt(b))^n 与 (a+sqrt(b))^n共轭,两者展开后会相互抵销,所以(

HDU4565 So Easy! 矩阵快速幂外加数学

easy 个屁啊,一点都不easy,题目就是要求公式的值,但是要求公式在最后的取模前的值向上取整,再取模,无脑的先试了快速幂 double  fmod来做,结果发现是有问题的,这题要做肯定得凑整数,凑整  题目给 a+√b 那么加上a-√b就可以了,可是这样加上后面怎么处理还得减去,想了半年也想不出来, 原来用了负数的共轭思想,还有就是题目给的b的范围 是 ((a-1)*(a-1),a*a),所以 a-√b的值的 无论多少次方 的值都是小于1的,所以对于原式子 改装成 ((a + √b) ^n+

2013长沙邀请赛A So Easy!(矩阵快速幂,共轭)

So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2286    Accepted Submission(s): 710 Problem Description A sequence Sn is defined as:Where a, b, n, m are positive integers.┌x┐is the ceil

hdu4565 So Easy!(矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565 题解:(a+√b)^n=xn+yn*√b,(a-√b)^n=xn-yn*√b, (a+√b)^n=2*xn-(a-√b)^n,(0<=a-√b<=1),所以整数部分就是2*xn 然后再利用两个公式 (a+√b)^(n+1)=(a+√b)*(xn+yn*√b) (a-√b)^(n+1)=(a-√b)*(xn-yn*√b) 联立得到 x(n+1)=a*xn+b*yn y(n+1)=xn+a*yn

HDU2256&amp;&amp;HDU4565:给一个式子的求第n项的矩阵快速幂

HDU2256 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2256 题意:求(sqrt(2)+sqrt(3))^2n%1024是多少. 这个题算是hdu4565的一个常数版本了,所以我们先说这道题.对于这道题的做法我们可以计算((sqrt(2)+sqrt(3))^2)^n=(5+2*sqrt(6))^n,对于(5+2*sqrt(6))^n我们知道答案必定是以an+bn*sqrt(6),而对于下一项我们只需要求(an+bn*sqrt(6))*(5

【构造共轭函数+矩阵快速幂】HDU 4565 So Easy! (2013 长沙赛区邀请赛)

链接 :click here~~ 题意: A sequence Sn is defined as: Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn. You, a top coder, say: So easy! [解题思路] 给一张神图,推理写的灰常明白了,关键是构造共轭函数,这一点实在是要有数学知识的理论基础,推出了递推式,接下

矩阵快速幂 HDU 4565 So Easy!(简单?才怪!)

题目链接 题意: 思路: 直接拿别人的图,自己写太麻烦了~ 然后就可以用矩阵快速幂套模板求递推式啦~ 另外: 这题想不到或者不会矩阵快速幂,根本没法做,还是2013年长沙邀请赛水题,也是2008年Google Codejam Round 1A的C题. #include <bits/stdc++.h> typedef long long ll; const int N = 5; int a, b, n, mod; /* *矩阵快速幂处理线性递推关系f(n)=a1f(n-1)+a2f(n-2)+.

zoj 2974 Just Pour the Water矩阵快速幂

Just Pour the Water Time Limit: 2 Seconds      Memory Limit: 65536 KB Shirly is a very clever girl. Now she has two containers (A and B), each with some water. Every minute, she pours half of the water in A into B, and simultaneous pours half of the

HDU 2256 Problem of Precision (矩阵快速幂)

HDU 2256 Problem of Precision (矩阵快速幂) ACM 题目地址:HDU 2256 Problem of Precision 题意: 给出一个式子,求值. 分析: 推起来最后那步会比较难想. 具体过程见: 表示共轭只听说过复数的和图的... 这构题痕迹好明显... 跟基友开玩笑说:如果遇到这种题,推到Xn+Yn*sqrt(6)这步时,打表最多只能打到10就爆int了,这是输出正解和Xn,说不定眼神好能发现ans = Xn * 2 - 1呢.= =... 代码: /*