讨论 / 求教啊
小胖无敌 2013-06-16 08:53:00
点我顶贴 收藏 删除
这题的数据范围怎么搞啊,

我定义变量范围能力可弱了,呃呃呃

亲,能不能告诉我定义变量有什么可注意的,还有怎么根据题中给的范围算出来自己算法的最大限制,若是把所有的变量都定义成int64有什么严重后果,本人自己noip曾经笔算过一道题,对拍了一下,结果就是计算失误,拍没了一等奖,留下严重阴影,求教lz及各大牛,指点一下悲催的我吧,相信有了你们我不会再悲催了

若是我洞明了,有多少分,给多少分啊,别嫌我分少啊,牛们

#1 李淑欣@2013-06-16 02:07:00
回复 删除
小胖子。。这里
#2 神之水灵@2013-06-16 02:07:00
回复 删除
给我分!!

三个人,一人18分,分一下

#3 小胖无敌@2013-06-16 08:53:00
回复 删除
就给亲的师姐

师姐啊,没少麻烦你哦,亲情给分,一定会涨人品的哟,考完试,咱们也许就同级了哦,到时请你吃饭啊,郑重申明,本分献给我的师姐及注定辉煌的oi时代啊

#4 潘鹤翔@2014-02-05 17:50:25
回复 删除
#include <cstdio>

#include <cstdlib>

#include <algorithm>

#include <cstring>

#include <string>

typedef long long int64;

const int maxK = 1000010;

struct Matrix

{

int ele[3][3]; static int Mod;

Matrix() {memset(ele, 0, sizeof ele);}

Matrix(const Matrix& b) {*this = b;}

Matrix& operator=(const Matrix& b)

{memcpy(ele, b.ele, sizeof ele); return *this;}

int* const operator[](const int& Ind) {return ele[Ind];}

const int* const operator[](const int& Ind) const {return ele[Ind];}

Matrix& operator*=(const Matrix& b)

{

static Matrix res;

for (int i = 0; i < 3; ++i)

for (int j = 0; j < 3; ++j)

{

int64 tmp = 0;

for (int k = 0; k < 3; ++k)

tmp += (int64)ele[i][k] * b[k][j];

res[i][j] = tmp % Mod;

}

return *this = res;

}

} matr[maxK], A, B, C;

int Fib[maxK << 3], Ind_Fib[maxK], Ind_Cyc[maxK], len[maxK], p, K, Matrix::Mod = 0;

int64 n;

Matrix pow(const Matrix& a, int64 n)

{

Matrix res, tmp(a);

res[0][0] = res[1][1] = res[2][2] = 1;

for (; n; n >>= 1, tmp *= tmp) if (n & 1) res *= tmp;

return res;

}

int pow(int a, int64 n, int Mod)

{

int64 res = 1, tmp = a;

for (; n; n >>= 1, (tmp *= tmp) %= Mod) if (n & 1) (res *= tmp) %= Mod;

return res;

}

int gcd(int n, int m)

{

for (int r; m; n = m, m = r) r = n % m;

return n;

}

int main()

{

scanf("%lld%d%d", &n, &K, &p);

Matrix::Mod = p;

Fib[1] = Fib[2] = 1;

for (int i = 3; ; ++i)

{

Fib[i] = (Fib[i - 1] + Fib[i - 2]) % K;

if (!Ind_Fib[Fib[i]]) Ind_Fib[Fib[i]] = i;

if (Fib[i] == 1 && Fib[i - 1] == 1) break;

}

int tmp = K, mul_Inv = 1;

for (int i = 2; i * i <= tmp; ++i)

if (tmp % i == 0)

{

mul_Inv *= i - 1;

while ((tmp /= i) % i == 0) mul_Inv *= i;

}

if (tmp > 1) mul_Inv *= tmp - 1;

A[0][1] = A[1][0] = A[1][1] = A[2][2] = 1;

B[0][0] = B[1][1] = B[2][2] = 1;

C[0][0] = C[1][1] = C[2][2] = 1;

memset(Ind_Cyc, 0xff, sizeof Ind_Cyc);

int tot = 0, ths = 1, ans = 0; int64 totlen = 0;

for (; Ind_Cyc[ths] == -1; ++tot)

{

if (gcd(ths, K) > 1 || !Ind_Fib[pow(ths, mul_Inv - 1, K)])

{

for (int i = 0; i < tot; ++i) B *= matr[i];

B *= pow(A, n - totlen);

ans = ((B[1][0] - B[2][0]) % p + p) % p;

printf("%d\n", ans);

return 0;

}

Ind_Cyc[ths] = tot;

int nxt = pow(ths, mul_Inv - 1, K);

len[tot] = Ind_Fib[nxt];

if (n < totlen + len[tot])

{

for (int i = 0; i < tot; ++i) B *= matr[i];

B *= pow(A, n - totlen);

ans = ((B[1][0] - B[2][0]) % p + p) % p;

printf("%d\n", ans);

return 0;

}

totlen += len[tot];

matr[tot] = pow(A, len[tot]);

++matr[tot][2][0] %= p;

++matr[tot][2][1] %= p;

ths = ((int64)ths * Fib[len[tot] - 1]) % K;

}

int start = Ind_Cyc[ths];

for (int i = 0; i < start; ++i) B *= matr[i], n -= len[i];

totlen = 0;

for (int i = start; i < tot; ++i) C *= matr[i], totlen += len[i];

B *= pow(C, n / totlen);

n %= totlen, totlen = 0;

for (int i = start; i < tot; ++i)

{

if (n < totlen + len[i])

{

B *= pow(A, n - totlen);

ans = ((B[1][0] - B[2][0]) % p + p) % p;

printf("%d\n", ans);

return 0;

}

B *= matr[i];

totlen += len[i];

}

return 0;

}

查看更多回复
提交回复