您的位置:首页 > 其它

hdu 5451 Best Solver(矩阵乘法+数论)

2015-09-29 20:14 302 查看
题目链接:hdu 5451 Best Solver

解题思路

因为取模的数很小,所以暴力找打循环节,然后求解。

代码

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;
const int maxn = 46340;
typedef int Mat[2][2];

struct State {
int d, p;
State (int d = 0, int p = 0): d(d), p(p) {}
bool operator < (const State& u) const { return d < u.d; }
};

int N, M;
Mat X, Y;
vector<State> G[maxn];

void mul(Mat a, Mat b, Mat& c) {
Mat s;
memset(s, 0, sizeof(s));
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++)
s[i][j] = (s[i][j] + a[i][k] * b[k][j] % M) % M;
}
}

memcpy(c, s, sizeof(s));
}

void init () {
scanf("%d%d", &N, &M);
X[0][0] = X[1][1] = 5 % M;
X[1][0] = 2 % M, X[0][1] = 12 % M;
memcpy(Y, X, sizeof(X));
for (int i = 0; i < M; i++) G[i].clear();
}

int solve () {

int start = 0, cnt = 1;
while (!start) {
int a = X[0][0], b = X[1][0];
State u = State(b, cnt);

for (int i = 0; i < G[a].size(); i++)
if (G[a][i].d == b)
start = G[a][i].p;

mul(X, X, X);
G[a].push_back(u);
cnt++;
}

cnt -= (start + 1);
memcpy(X, Y, sizeof(Y));
for (int i = 0; i < min(start, N); i++)
mul(X, X, X);

if (N > start) {
N -= start;
N = N % cnt;
for (int i = 0; i < N; i++)
mul(X, X, X);
}

mul(X, Y, X);
return (2 * X[0][0] - 1 + M) % M;
}

int main () {
int cas;
scanf("%d", &cas);
for (int kcas = 1; kcas <= cas; kcas++) {
init();
printf("Case #%d: %d\n", kcas, solve());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: