Iterated Linear Function

链接:http://acm.hust.edu.cn/vjudge/problem/401745/origin

题目:Consider a linear function f(x) = Ax + B. Let's define g(0)(x) = x and g(n)(x) = f(g(n - 1)(x)) for n > 0. For the given integer values A, B, n and x find the value of g(n)(x) modulo 109 + 7.

题意:求把abnx带入上述公式的结果对1e9+7取模的结果。

分析:非常多的乘方运算,可以推出通项公式用快速幂求,也可以直接用矩阵描述这个公式,在用矩阵快速幂直接得出结果。(这是我第一次手写矩阵快速幂,非常的丑陋。。)

题解:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <cstring>
#include <functional>
#include <cmath>
using namespace std;

__int64 mn;
__int64 a,b,n,x;
__int64 m[2][2],mt[2][2],mans[2][2],manst[2][2],ans[2];

void s()
{
	m[0][0]=((mt[0][0]*mt[0][0])%mn+(mt[0][1]*mt[1][0])%mn)%mn;
	m[0][1]=((mt[0][0]*mt[0][1])%mn+(mt[0][1]*mt[1][1])%mn)%mn;
	m[1][0]=((mt[1][0]*mt[0][0])%mn+(mt[1][1]*mt[1][0])%mn)%mn;
	m[1][1]=((mt[1][0]*mt[0][1])%mn+(mt[1][1]*mt[1][1])%mn)%mn;
	mt[0][0]=m[0][0];
	mt[0][1]=m[0][1];
	mt[1][0]=m[1][0];
	mt[1][1]=m[1][1];
}

void t()
{
	ans[0]=((mans[0][0]*ans[0])%mn+mans[0][1])%mn;
}

int main()
{
	//freopen("in.txt","r",stdin);
	mn=1000000007;
	while(~scanf("%I64d %I64d %I64d %I64d",&a,&b,&n,&x))
	{
		mt[0][0]=m[0][0]=a;
		mt[0][1]=m[0][1]=b;
		mt[1][0]=m[1][0]=0;
		mt[1][1]=m[1][1]=1;
		ans[0]=x;
		ans[1]=1;
		manst[0][0]=mans[0][0]=1;
		manst[0][1]=mans[0][1]=0;
		manst[1][0]=mans[1][0]=0;
		manst[1][1]=mans[1][1]=1;
		while(n>0)
		{
			if(n&1) 
			{
				mans[0][0]=((manst[0][0]*mt[0][0])%mn+(manst[0][1]*mt[1][0])%mn)%mn;
				mans[0][1]=((manst[0][0]*mt[0][1])%mn+(manst[0][1]*mt[1][1])%mn)%mn;
				mans[1][0]=((manst[1][0]*mt[0][0])%mn+(manst[1][1]*mt[1][0])%mn)%mn;
				mans[1][1]=((manst[1][0]*mt[0][1])%mn+(manst[1][1]*mt[1][1])%mn)%mn;
				manst[0][0]=mans[0][0];
				manst[0][1]=mans[0][1];
				manst[1][0]=mans[1][0];
				manst[1][1]=mans[1][1];
			}
			s();
			n/=2;
		}
		t();
		printf("%I64d\n",ans[0]);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值