本文主要是介绍HDU - 4291 - A Short problem(循环节+矩阵快速幂),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4291
思路:如果直接利用n做三次矩阵快速幂求解是不对的。因为三次快速幂对1000000007取模,会超精度。所以必须本地处理寻找每层的循环节,最外层最1000000007取模,则找到最外层的循环节是222222224,次外层对222222224取模,找到次外层循环节是183120。接下来利用这三个不同的mod进行三层快速幂。
暴力查找你循环节代码:
/**** █████▒█ ██ ▄████▄ ██ ▄█▀ ██████╗ ██╗ ██╗ ██████╗* ▓██ ▒ ██ ▓██▒▒██▀ ▀█ ██▄█▒ ██╔══██╗██║ ██║██╔════╝* ▒████ ░▓██ ▒██░▒▓█ ▄ ▓███▄░ ██████╔╝██║ ██║██║ ███╗* ░▓█▒ ░▓▓█ ░██░▒▓▓▄ ▄██▒▓██ █▄ ██╔══██╗██║ ██║██║ ██║* ░▒█░ ▒▒█████▓ ▒ ▓███▀ ░▒██▒ █▄ ██████╔╝╚██████╔╝╚██████╔╝* ▒ ░ ░▒▓▒ ▒ ▒ ░ ░▒ ▒ ░▒ ▒▒ ▓▒ ╚═════╝ ╚═════╝ ╚═════╝* ░ ░░▒░ ░ ░ ░ ▒ ░ ░▒ ▒░* ░ ░ ░░░ ░ ░ ░ ░ ░░ ░* ░ ░ ░ ░ ░**/
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define ll long long
const int maxn = 2e5 + 7;
const int mod = 1e9 + 7;int main()
{ll a = 0, b = 1;for(ll i = 1; ; i++){a = (3 * b + a) % mod;swap(a, b);if(a == 0 && b == 1){cout << i <<endl;break;}}
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2;
ll n, k;
int MOD;
struct Matrix
{ll m[MAXN][MAXN];void init(int x){memset(m, 0, sizeof(m));for(int i = 0; i < MAXN; i++){m[i][i] = x;}}Matrix operator * (const Matrix &a) const{Matrix res;res.init(0);for(int i = 0; i < MAXN; i++)for(int j = 0; j < MAXN; j++)for(int k = 0; k < MAXN; k++)res.m[i][j] = (res.m[i][j] + (m[i][k] * a.m[k][j]) % MOD) % MOD;return res;}
};Matrix quickPow(Matrix x, ll p)
{Matrix res;res.init(1);x = x * res;while(p){if(p & 1) res = res * x;p >>= 1;x = x * x;}return res;
}Matrix a, x;void init()
{a.init(0);a.m[0][0] = 3; a.m[0][1] = 1;a.m[1][0] = 1; a.m[1][1] = 0;x.init(0);x.m[0][0] = 1;x.m[1][0] = 0;
}
ll solve(ll n)
{init();return (quickPow(a, n) * x).m[1][0];
}
int main()
{while(~scanf("%lld",&k)){MOD = 183120;k = solve(k);MOD = 222222224;k = solve(k);MOD = 1000000007;k = solve(k);printf("%lld\n",k);}return 0;
}
这篇关于HDU - 4291 - A Short problem(循环节+矩阵快速幂)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!