LightOJ 1070 - Algebraic Problem 矩阵快速幂

题链:http://lightoj.com/volume_showproblem.php?problem=1070

1070 - Algebraic Problem

PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

Given the value of a+b and ab you will have to find the value of an+bna and b not necessarily have to be real numbers.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case contains three non-negative integers, p, q and n. Here p denotes the value of a+b and q denotes the value of ab. Each number in the input file
fits in a signed 32-bit integer. There will be no such input so that you have to find the value of 00.

Output

For each test case, print the case number and (an+bn) modulo 264.

Sample Input

Output for Sample Input


2

10 16 2

7 12 3


Case 1: 68

Case 2: 91

题意:

给你p=a+b, q=ab

算出 (a^n+b^)mod2^64

做法:

mod 2^64所以开 unsigned long long ,llu 就行了,达到上限会自动取模的。

然后就是公式了。我是在推公式中找到的规律。

a^2+b^2=(a+b)*(a+b)-2*a*b

a^3+b^3=(a^2+b^2)*(a+b)-a*b(a+b)

a^4+b^4=(a^3+b^3)*(a+b)-a*b(a^2+b^2)

设G(n)=a^n+b^n

G(n)=G(n-1)*p-G(G-2)*q

然后就是快速幂了。.

#include<stdio.h>
#include<string.h>
#define Matr 5 //矩阵大小,注意能小就小   矩阵从1开始   所以Matr 要+1   最大可以100
#define ll unsigned long long
struct mat//矩阵结构体,a表示内容,size大小 矩阵从1开始   但size不用加一
{
    ll a[Matr][Matr];
    mat()//构造函数
    {
        memset(a,0,sizeof(a));
    }
};
int Size=  2; 

mat multi(mat m1,mat m2)//两个相等矩阵的乘法,对于稀疏矩阵,有0处不用运算的优化
{
    mat ans=mat();
    for(int i=1;i<=Size;i++)
        for(int j=1;j<=Size;j++)
            if(m1.a[i][j])//稀疏矩阵优化
                for(int k=1;k<=Size;k++)
                    ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k]); //i行k列第j项
    return ans;
}

mat quickmulti(mat m,ll n)//二分快速幂
{
    mat ans=mat();
    int i;
    for(i=1;i<=Size;i++)ans.a[i][i]=1;
    while(n)
    {
        if(n&1)ans=multi(m,ans);//奇乘偶子乘 挺好记的.
        m=multi(m,m);
        n>>=1;
    }
    return ans;
}

void print(mat m)//输出矩阵信息,debug用
{
    int i,j;
    printf("%d\n",Size);
    for(i=1;i<=Size;i++)
    {
        for(j=1;j<=Size;j++)
			printf("%llu ",m.a[i][j]);
        printf("\n");
    }
}
int main()
{
	/*
	ll a,b;
	while(scanf("%llu",&a)!=EOF)
		printf("%llu\n",-a+18446744073709551615+1);
	*/
	int t;
	int cas=1;
	scanf("%d",&t);
	while(t--)
	{
		ll p,q,n;
		int p1,q1;
		scanf("%lld%lld%llu",&p,&q,&n);// p a+b q ab 

		ll tem=18446744073709551615-q+1;

		mat gouzao=mat(),chu=mat();//构造矩阵  初始矩阵
		chu.a[1][1]=p;
		chu.a[1][2]=p*p+2*tem;
		chu.a[1][3]=q;
		printf("Case %d: ",cas++);
		if(n==0)
			printf("2\n");
		else if(n==1)
			printf("%llu\n",p);
		else if(n==2)
			printf("%llu\n",p*p+2*tem);
		else
		{
			gouzao.a[1][1]=0;
			gouzao.a[2][1]=1;
			gouzao.a[1][2]=tem;
			gouzao.a[2][2]=p;
			//print(gouzao);
			printf("%llu\n",multi(chu,quickmulti(gouzao,n-2)).a[1][2]);
		}
	}
	return 0;
}

/*
ans^=n -
mat ans=mat();
ans.size=Size;
初始化ans矩阵
ans=quickmulti(ans,n,mod);

void print(mat m)//输出矩阵信息,debug用
{
    int i,j;
    printf(%dn,m.size);
    for(i=1;i=m.size;i++)
    {
        for(j=1;j=m.size;j++)printf(%d ,m.a[i][j]);
        printf(n);
    }
}
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-17 06:00:40

LightOJ 1070 - Algebraic Problem 矩阵快速幂的相关文章

LightOJ 1070 Algebraic Problem (推导+矩阵快速幂)

题目链接:LightOJ 1070 Algebraic Problem 题意:已知a+b和ab的值求a^n+b^n.结果模2^64. 思路: 1.找递推式 得到递推式之后就是矩阵快速幂了 注意:模2^64,定义成unsigned long long 类型,因为无符号类型超过最大范围的数与该数%最大范围 的效果是一样的. AC代码: #include<stdio.h> #include<string.h> #define LL unsigned long long struct Ma

LightOJ 1070 Algebraic Problem (推导+矩阵高速幂)

题目链接:problem=1070">LightOJ 1070 Algebraic Problem 题意:已知a+b和ab的值求a^n+b^n.结果模2^64. 思路: 1.找递推式 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > 得到递推式之后就是矩阵高速幂了 注意:模2^64,定

hdu 1757 A Simple Math Problem 矩阵快速幂

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757 Lele now is thinking about a simple function f(x).If x < 10 f(x) = x.If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);And ai(0<=i<=9) can only be 0 or 1 .Now, I w

hdu1757 A Simple Math Problem(矩阵快速幂)

题目: A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3522    Accepted Submission(s): 2130 Problem Description Lele now is thinking about a simple function f(x). If x < 10 f

HDU 4291 A Short problem(矩阵快速幂+循环节)

题目链接": http://acm.hdu.edu.cn/showproblem.php?pid=4291 题意: g(0)=0,g(1)=1; g(n) = 3g(n - 1) + g(n - 2): 求g(g(g(n))) mod 109 + 7 分析: 首先我们得认识到,如果一层一层算是必定会超时的. 其次,取模运算是有循环节的. step1我们找出g(x)%1000000007的循环节 mod1 step2 设g(g(n)) = g(x) x=g(n) 对mod1 取模得到mod2. 剩

LightOJ 1070 - Algebraic Problem 推导+矩阵快速幂

http://www.lightoj.com/volume_showproblem.php?problem=1070 思路:\({(a+b)}^n =(a+b){(a+b)}^{n-1} \) \((ab)C_{n}^{r}a^{n-r}b{r} = C_{n+2}^{r}a^{n-r+2}b{r} - a^{n+2} - b^{n+2} \) 综上\( f(n) = (a+b)f(n-1)-(ab)f(n-2) \) /** @Date : 2016-12-19-19.53 * @Author

FZU - 1692 Key problem 矩阵快速幂

题目大意:有n个人围成一圈玩游戏,游戏有m个回合.每个人每回合能得到(L * 左边那个人的苹果数量) + (R * 右边那个人的苹果数量),问最后每个人得到的苹果数量 解题思路:矩阵的话比较好写,就不解释了,关键是怎么将矩阵乘法的复杂度下降,因为每个人每回合矩阵变化都是相同的,所以只需要求出第一行就可以了,经过偏移就可以得到其他行的了 这里还有一个剪枝点,传参时要用引用,不然会超时... #include<cstdio> #include<cstring> typedef long

dutacm.club Water Problem(矩阵快速幂)

Water Problem Time Limit:3000/1000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total Submissions:1228   Accepted:121 [Submit][Status][Discuss] Description 函数 f:Z+→Z .已知 f(1),f(2) 的值,且对于任意 x>1,有 f(x+1)=f(x)+f(x?1)+sin(πx2) . 求 f(n) 的

A Simple Math Problem(矩阵快速幂)(寒假闭关第一题,有点曲折啊)

A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 155 Accepted Submission(s): 110   Problem Description Lele now is thinking about a simple function f(x). If x < 10 f(x) = x.If