hdu 5895(矩阵快速幂+欧拉函数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5895

f(n)=f(n-2)+2*f(n-1)

f(n)*f(n-1)=f(n-2)*f(n-1)+2*f(n-1)*f(n-1);

2*f(n-1)*f(n-1)=f(n)*f(n-1)-f(n-2)*f(n-1);

累加可得 g(n) = f(n)*f(n+1)/2

然后这个公式:A^x % m = A^(x%phi(m)+phi(m)) % m (x >= phi(m))

反正比赛没做出来.

#include <bits/stdc++.h>
#define LL long long
using namespace std;
struct Maxtri{
    LL v[2][2];
    Maxtri(){memset(v,0,sizeof(v));}
}ori;
LL n, y, x, s, mod ;
Maxtri mult(Maxtri a,Maxtri b){
    Maxtri temp;
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            for(int k=0;k<2;k++){
                temp.v[i][j] = (temp.v[i][j]+(a.v[i][k]*b.v[k][j])%mod)%mod;
            }
        }
    }
    return temp;
}
LL pow_mod(Maxtri a,LL n){
    if(n==0) return 0;
    if(n==1) return 1;
    if(n==2) return 2;
    n-=2;
    Maxtri ans;
    for(int i=0;i<2;i++){
        ans.v[i][i] = 1;
    }
    while(n){
        if(n&1) ans = mult(ans,a);
        a = mult(a,a);
        n>>=1;
    }
    return (ans.v[0][0]*2+ans.v[0][1])%mod;
}
LL pow_mod1(LL a,LL n,LL mod){
    LL ans = 1;
    while(n){
        if(n&1) ans = ans*a%mod;
        a = a*a%mod;
        n>>=1;
    }
    return ans;
}
LL Phi(LL x)
{
    LL ans = x;
    for(LL i=2LL; i*i<=x; i++)
    {
        if(x % i == 0)
        {
            ans -= ans/i;
            while(x % i == 0)
                x /= i;
        }
    }
    if(x > 1)
        ans -= ans/x;
    return ans;
}
int main(){
    ori.v[0][0] = 2,ori.v[0][1] = 1;
    ori.v[1][0] = 1,ori.v[1][1] = 0;
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        scanf("%lld%lld%lld%lld",&n, &y, &x, &s);
        s++;
        LL phi = 2*Phi(s);
        mod = 2*phi;
        LL fn = pow_mod(ori,n*y);
        LL fn1 = pow_mod(ori,n*y+1);
        LL ans = ((fn*fn1)%mod/2);
        ans+=phi;
        printf("%lld\n",pow_mod1(x,ans,s)%s);
    }
    return 0;
}
时间: 2024-08-08 16:52:11

hdu 5895(矩阵快速幂+欧拉函数)的相关文章

HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂

装载自:http://www.cnblogs.com/183zyz/archive/2012/05/11/2495401.html 题目让求一个函数调用了多少次.公式比较好推.f[n] = f[n-1]*f[n-2].然后a和b系数都是呈斐波那契规律增长的.需要先保存下来指数.但是太大了.在这里不能用小费马定理.要用降幂公式取模.(A^x)%C=A^(x%phi(C)+phi(C))%C(x>=phi(C)) Phi[C]表示不大于C的数中与C互质的数的个数,可以用欧拉函数来求. 矩阵快速幂也不

HDU 5895 矩阵快速幂+高次幂取模

HDU 5895 Mathematician QSC 题意:已知f(n)=2*f(n-1)+f(n-2), g(n)=∑f(i)²(0<=i<=n), 给出n,x,y,s, 求x^(g(n*y))%(s+1); 思路:OEIS查到了g(n)=f(n)*f(n+1)/2, f(n)可以用矩阵快速幂求得, 有一个定理可以用于高次幂取模 x^n %k=x^(n%phi(k)+phi(k)) %k, 此处phi(x)为欧拉函数,但是在对幂次取模时存在一个除2, 又因为(a/b)%k=(a%bk)/b,

BZOJ1408 NOI2002 Robot 快速幂+欧拉函数

题意:分别求所有质因数都不同且质因数个数为奇数个.偶数个的数的欧拉函数和,和质因数存在重复的数的欧拉函数和 题解: 说书题……前面一大串就是用一种比较有趣的语言定义欧拉函数. 显然我们只需要求出所有军人ans1和政客ans2,然后用求得的M减去独立数和就是学者的独立数和了. 由于善良的出题人已经帮我们把M给质因分解了,因此我们假定当前已经得到了ans1和ans2,那么根据欧拉函数的定义,ans1'=ans1+ans2*(p-1),ans2'=ans2+ans1*(p-1),因为新加入的质因子会让

Super A^B mod C 快速幂+欧拉函数降幂

uper A^B mod C Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,C<=1000000000,1<=B<=10^1000000). Input There are

Product Oriented Recurrence(Codeforces Round #566 (Div. 2)E+矩阵快速幂+欧拉降幂)

传送门 题目 \[ \begin{aligned} &f_n=c^{2*n-6}f_{n-1}f_{n-2}f_{n-3}&\\end{aligned} \] 思路 我们通过迭代发现\(f_n\)其实就是由\(c^{x_1},f_1^{x_2},f_2^{x_3},f_3^{x_4}\)相乘得到,因此我们可以分别用矩阵快速幂求出\(x_1,x_2,x_3,x_4\),最后用快速幂求得答案. 对\(f_1,f_2,f_3\): \[ \begin{aligned} (x_n&&

1408: [Noi2002]Robot|快速幂|欧拉函数

真是一道神题,语文渣渣表示已经给题意描述跪烂了.. 独立数显然就是欧拉函数φ 然后政客军人他们的分解成的奇素数的指数显然都是1,最初的思想就是暴力枚举只有1个奇函数的情况,2个,3个----这样显然是会超时,可以发现欧拉函数是满足积性的,所以可以放到一起乘起来算用一种类似于DP的"前缀和"的思想来做 ans1表示当前有奇数个奇数质因子的"前缀和" ans2表示当前有偶数个奇数质因子的"前缀和" 然后学者的独立数可以用总和减去前两个的和,因为欧拉函

hdu--4549--费马小定理&amp;快速幂&amp;欧拉函数

这题 蛮复杂的. 我自己做的时候 无法处理完 最后一步公式的转换 后来看到别人说这是 费马小定理 与 欧拉函数的思想下的转换 可是 我自己还推导不出来啊... 首先 你要发现f[n]=a^x * b^y其实指数x 与 y是fib数列中的f[n-1]与f[n]项( n>=1 并且数列是0 1 1 2 3 5 8 ...) 那么 其实题目就转换成了 f[n] = a^fib[n-1] * b^fib[n] % mod; 这边 不必要对于 a^fib[n-1]与 b^fib[n] 单独再在括号进行取模

E. Product Oriented Recurrence(矩阵快速幂+欧拉降幂)

题目链接: https://codeforces.com/contest/1182/problem/E 题目大意:  f(x)=c^(2x−6)⋅f(x−1)⋅f(x−2)⋅f(x−3)    for x≥4x≥4. 给你f1,f2,f3,n,c.求第n项的结果. 具体思路: 看到递推式想到用矩阵快速幂优化:但是如果都是乘法的话,是无法化成矩阵相乘的形式的.然后就开始想怎么将乘法转换成加法.推了一个多小时也没有推出来.. 具体的解题过程如下: 对于每一项,这一项里面包含的f1 和 f2 和 f3

hdu 2814 快速求欧拉函数

1 /** 2 大意: 求[a,b] 之间 phi(a) + phi(a+1)...+ phi(b): 3 思路: 快速求欧拉函数 4 **/ 5 6 #include <iostream> 7 #include <cstring> 8 using namespace std; 9 #define Max 3000000 10 11 long long phi[Max+5]; 12 int prime[Max/10]; 13 bool flag[Max+5]; 14 15 void