HDU 4686 Arc of Dream 矩阵快速幂,线性同余 难度:1

http://acm.hdu.edu.cn/showproblem.php?pid=4686

当看到n为小于64位整数的数字时,就应该有个感觉,acm范畴内这应该是道矩阵快速幂

Ai,Bi的递推式题目已经给出,

Ai*Bi=Ax*Bx*(Ai-1*Bi-1)+Ax*By*Ai-1+Bx*Ay*Bi-1+Ay*By

AoD(n)=AoD(n-1)+AiBi

构造向量I{AoD(i-1),Ai*Bi,Ai,Bi,1}

初始向量为I0={0,A0*B0,A0,B0,1}

构造矩阵A{

1,0,0,0,0,

1,Ax*Bx,0,0,0,
0,Ax*By,Ax,0,0,

0,Bx*Ay,0,Bx,0,

0,Ay*By,Ay,By,1,

}

则I0*(A)^n则为包含结果的向量,此时I[0]即为解答

注意:

1.据说有n=0,直接输出0

2.long long的使用

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll n,ao,bo,ax,bx,ay,by;
void init(ll** ans,ll** base){
        fill(ans[0],ans[0]+5,0);
        fill(base[0],base[0]+25,0);
        ans[0][1]=ao*bo%mod;
        ans[0][2]=ao;
        ans[0][3]=bo;
        ans[0][4]=1;
        base[0][0]=1;
        base[1][0]=1;base[1][1]=ax*bx%mod;
        base[2][1]=ax*by%mod;base[2][2]=ax;
        base[3][1]=bx*ay%mod;base[3][3]=bx;
        base[4][1]=ay*by%mod;base[4][2]=ay;base[4][3]=by;base[4][4]=1;
}
void print(ll **t ,int m,int r){
        for(int i=0;i<m;i++){
                for(int j=0;j<r;j++){
                        printf("%I64d ",t[i][j]);
                }
                puts("");
        }
}

void multi(ll** t,ll** b,ll ** tmp,int m,int r,int s){
        fill(tmp[0],tmp[0]+m*s,0);
        for(int i=0;i<m;i++){
                for(int j=0;j<s;j++){
                        for(int k=0;k<r;k++){
                                tmp[i][j]+=(t[i][k]*b[k][j])%mod;
                                tmp[i][j]%=mod;
                        }
                }
        }
}

void qpow(ll** ans,ll ** base,ll**tmp,ll time,int r,int m){
        while(time>0){
                if(time&1){
                        multi(ans,base,tmp,r,m,m);
                        copy(tmp[0],tmp[0]+r*m,ans[0]);
                        time--;
                }
                multi(base,base,tmp,m,m,m);
                copy(tmp[0],tmp[0]+m*m,base[0]);
                time>>=1;
        }
}

int main(){
        ll ** ans = new ll*[1],**tmp=new ll*[5],** base =new ll*[5];
        ans[0]=new ll[5],tmp[0]=new ll[25],base[0]=new ll[25];
        for(int i=1;i<5;i++){
                tmp[i]=tmp[0]+5*i;
                base[i]=base[0]+5*i;
        }
        while(scanf("%I64d",&n)==1){
                scanf("%I64d%I64d%I64d",&ao,&ax,&ay);
                ao%=mod;ax%=mod;ay%=mod;
                scanf("%I64d%I64d%I64d",&bo,&bx,&by);
                bo%=mod;bx%=mod;by%=mod;
                if(n==0)puts("0");
                else {
                        init(ans,base);
                        qpow(ans,base,tmp,n,1,5);
                        printf("%I64d\n",ans[0][0]);
                }

        }
        delete ans;delete base;delete tmp;
        return 0;
}

  

时间: 2024-12-16 09:00:40

HDU 4686 Arc of Dream 矩阵快速幂,线性同余 难度:1的相关文章

HDU 4686 Arc of Dream(矩阵快速幂)

题目地址:HDU 4686 我去..因为忘记把函数里的k定义成64位的,导致TLE了一晚上...晕.. 这题没什么技巧,就是根据公式构造就行. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #in

HDOJ 4686 Arc of Dream 矩阵快速幂

矩阵快速幂: 根据关系够建矩阵 , 快速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2164    Accepted Submission(s): 680 Problem Description An Arc of Dream is a curve defined by following fun

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

[HDOJ 4686] Arc of Dream (矩阵快速幂) 两个公式 a(i) = a(i-1)*Ax+Ay b(i) = b(i-1)*Bx+By 求 0~(n-1) 的a(i)*b(i) 初始矩阵为                                       求幂矩阵为 a0                                                      Ax          0           0          0        

S - Arc of Dream 矩阵快速幂

An Arc of Dream is a curve defined by following function: where a 0 = A0 a i = a i-1*AX+AY b 0 = B0 b i = b i-1*BX+BY What is the value of AoD(N) modulo 1,000,000,007? InputThere are multiple test cases. Process to the End of File. Each test case con

hdu4686 Arc of Dream 矩阵快速幂

An Arc of Dream is a curve defined by following function: wherea0 = A0ai = ai-1*AX+AYb0 = B0bi = bi-1*BX+BYWhat is the value of AoD(N) modulo 1,000,000,007? 矩阵快速幂 1 #include<stdio.h> 2 #include<string.h> 3 typedef long long ll; 4 const int mod

HDOJ 4686 Arc of Dream 矩阵高速幂

矩阵高速幂: 依据关系够建矩阵 , 高速幂解决. Arc of Dream Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2164    Accepted Submission(s): 680 Problem Description An Arc of Dream is a curve defined by following fun

HDU 4686 Arc of Dream(快速幂矩阵)

题目链接 再水一发,构造啊,初始化啊...wa很多次啊.. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 1000000007 #define

HDU 4896 Minimal Spanning Tree(矩阵快速幂)

题意: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一个循环,接下来的9个点连回去的边都是一样的.预处理出5个点的所有连通状态,总共只有52种,然后对于新增加一个点和前面点的连边状态可以处理出所有状态的转移.然后转移矩阵可以处理出来了,快速幂一下就可以了,对于普通的矩阵乘法是sigma( a(i, k) * b(k, j) ) (1<=k<=N), 现在

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob