0
点赞
收藏
分享

微信扫一扫

2020牛客寒假算法基础集训营1——J.u's的影响力【矩阵快速幂 & 欧拉降幂】(附加强数据 & 注意坑点)


​​题目传送门​​

题目描述

本题测试样例已经更(jia)新(qiang)。

μ’s在九人齐心协力下,影响力越来越大了!
已知第一天影响力为 2020牛客寒假算法基础集训营1——J.u ,第二天影响力为 2020牛客寒假算法基础集训营1——J.u ,从第三天开始,每一天的影响力为前两天影响力的乘积再乘以 2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u 次方。 用数学语言描述是:
设第 2020牛客寒假算法基础集训营1——J.u 天的影响力为 2020牛客寒假算法基础集训营1——J.u ,那么 2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u,对于 2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u
她们想知道第 2020牛客寒假算法基础集训营1——J.u 天影响力是多少?
由于这个数可能非常大,只需要输出其对 2020牛客寒假算法基础集训营1——J.u

输入描述:

一行五个正整数:2020牛客寒假算法基础集训营1——J.u
2020牛客寒假算法基础集训营1——J.u

输出描述:

2020牛客寒假算法基础集训营1——J.u 天的影响力对 2020牛客寒假算法基础集训营1——J.u

输入

4 2 3 2 1

输出

72

说明

f(1)=2,f(2)=3,f(3)=f(1)*f(2)*2=12,f(4)=f(2)*f(3)*2=72

备注:

1000000007是素数。

题解

  • 显然2020牛客寒假算法基础集训营1——J.u可以用2020牛客寒假算法基础集训营1——J.u,2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u这三个因子表达出来。
    每一项a的幂次分别是2020牛客寒假算法基础集训营1——J.u从第三项开始每一项为前两项之和加1。
    2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u的幂次构成斐波那契数列:2020牛客寒假算法基础集训营1——J.u的幂次第一项是2020牛客寒假算法基础集训营1——J.u,第二项是2020牛客寒假算法基础集训营1——J.u2020牛客寒假算法基础集训营1——J.u的幂次第一项是2020牛客寒假算法基础集训营1——J.u,第二项是2020牛客寒假算法基础集训营1——J.u。之后每一项均为前两项之和。
  • 根据费马小定理,由于2020牛客寒假算法基础集训营1——J.u是素数,有2020牛客寒假算法基础集训营1——J.u。因此幂的指数对2020牛客寒假算法基础集训营1——J.u
  • 可以用矩阵快速幂2020牛客寒假算法基础集训营1——J.u求出2020牛客寒假算法基础集训营1——J.u幂次的第2020牛客寒假算法基础集训营1——J.u
  • 2020牛客寒假算法基础集训营1——J.u

特别注意(赛后加强数据)

  • 注意2020牛客寒假算法基础集训营1——J.u
    提供数据:1000000010 1000000007 3 5 1
  • 2020牛客寒假算法基础集训营1——J.u

AC-Code

#include <bits/stdc++.h>
//#pragma GCC optimize("O3")
//#pragma G++ optimize("O3")
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
#define
#define
#define

const int maxn = 3;
const int mod = 1e9 + 7;

struct mat {
int m[maxn][maxn];
mat() {
memset(m, 0, sizeof m);
}
}unit;

mat operator * (mat a, mat b) {
mat ret;
ll x;
for (ll i = 0; i < maxn; ++i)
for (ll j = 0; j < maxn; ++j) {
x = 0;
for (ll k = 0; k < maxn; ++k)
x += ((ll)a.m[i][k] * b.m[k][j]) % (mod - 1);
ret.m[i][j] = x % (mod - 1);
}
return ret;
}

void init_unit() {
for (int i = 0; i < maxn; ++i)
unit.m[i][i] = 1;
}

mat pow_mat(mat a, ll n) {
mat ret = unit;
while (n) {
if (n & 1) ret = ret * a;
a = a * a;
n >>= 1;
}
return ret;
}

ll q_mult(ll a, ll b, ll k) {
ll res = 0;
while (b) {
if (b & 1) res = (res + a) % k;
a = (a + a) % k;
b >>= 1;
}
return res;
}

ll q_pow(ll a, ll n, ll k) {
ll res = 1;
while (n) {
if (n & 1) res = q_mult(res, a, k);
a = (a * a) % k;
n >>= 1;
}
return res;
}

int main() {
ios;
init_unit();
ll n, x, y, a, b;
while (cin >> n >> x >> y >> a >> b) {

a = q_pow(a % mod, b, mod);
x = x % mod;
y = y % mod;
if (n == 1) {
cout << x << endl;
}
else if (n == 2) {
cout << y << endl;
}
else if (n == 3) {
cout << q_mult(q_mult(x, y, mod), a % mod, mod) << endl;
}
else {
mat mat_a, mat_b;
mat_b.m[0][0] = 1, mat_b.m[0][1] = 1, mat_b.m[0][2] = 0;
mat_b.m[1][0] = 1, mat_b.m[1][1] = 0, mat_b.m[1][2] = 1;
mat_b.m[2][0] = 0, mat_b.m[2][1] = 0, mat_b.m[2][2] = 0;

mat_a.m[0][0] = 1, mat_a.m[0][1] = 1, mat_a.m[0][2] = 0;

ll z1 = (mat_a * pow_mat(mat_b, n - 4)).m[0][0];
ll z2 = (mat_a * pow_mat(mat_b, n - 3)).m[0][0];
ll z3 = (mat_a * pow_mat(mat_b, n - 2)).m[0][0] - 1LL;

cout << q_mult(q_mult(q_pow(x, z1+mod-1, mod), q_pow(y, z2, mod), mod), q_pow(a % mod, z3 % (mod - 1), mod), mod) << endl;
}
}
}


举报

相关推荐

0 条评论