-
题意:多组输入,输入 (1 <= n ,m <=1000000000),(ans=0) ,当 (ans) 为偶数, (ans = ans imes 2 + 1),如果 (ans) 为奇数,那么 (ans = ans imes 2)。输出 (ans)。
-
题解:可以发现,答案要么是 (2 imes ans) ,即只有系数起作用,要么是 (2 imes ans + 1) ,即有一个 (1) 起作用,那么就可以构造 (ANS) 矩阵了。
(egin{bmatrix}ans&0\1&0end{bmatrix}) 然后发现其实,系数矩阵有两个,但是这两个的(a_{1,1})一定是 (2),然后为了维护 (ANS) 矩阵的 (a_{2,1}=1),所有的系数矩阵(a_{2,2} = 1),很容易得算出,如果要对 (ans) 乘二加一,显然系数矩阵的 (a_{1, 2} = 1) 否则 (a_{1, 2} = 0),然后得到两个系数矩阵 (A = egin{bmatrix}2&1\0&1end{bmatrix}, B = egin{bmatrix}2&0\0&1end{bmatrix}) 同时那么知道了系数矩阵,所以就可以用快速幂加速了,尽管有两个稀疏矩阵,其实发现他们相乘的数量都是 (left lfloor frac{n}{2} ight floor),就是 (A) 矩阵, 如果 (n%2 = 1) 的话 (A) 矩阵还要再左乘一下。 -
代码:
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e3 + 9;
ll mod = 6;
ll n, m;
struct Matrix {
ll a[10][10];
Matrix(){memset(a, 0, sizeof a);}
Matrix operator*(Matrix rhs)const {
Matrix ret;
for (int i = 0; i < 2; i ++) {
for (int j = 0; j < 2; j++){
for (int k = 0; k < 2; k++) {
(ret.a[i][j] += (a[i][k] * rhs.a[k][j] % mod)) %= mod;
}
}
}
return ret;
}
void pr() {
for (int i = 0; i < 2; i ++) {
for (int j = 0; j < 2; j++){
cout << a[i][j] << " ";
}
cout << endl;
}
}
};
Matrix ksm (Matrix A, int kk) {
if (kk == 1)return A;
Matrix ret;
bool f = 0;
while (kk) {
if (kk & 1) {
if (!f) {
ret = A;
f = 1;
} else
ret = ret * A;
}
kk >>= 1;
A = A * A;
}
return ret;
}
void solve() {
ll a[2][2] =
{
{2, 1},
{0, 1}
};
ll b[2][2] =
{
{2, 0},
{0, 1}
};
n = 0;
while (cin >> n >> m) {
mod = m;
Matrix A, B;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
A.a[i][j] = a[i][j];
B.a[i][j] = b[i][j];
}
}
Matrix C = A*B;
n--;
ll k = n/2;
Matrix ans;
ans.a[1][0] = 1;
ans.a[0][0] = 1;
if (k != 0) {
C = ksm(C, k);
ans = C * ans;
}
if (n % 2) {
ans = B * ans;
}
if (m == 1)cout << 0 << endl;
else
cout << ans.a[0][0] << endl;
}
}
signed main() {
int t = 1;//cin >> t;
while (t--) {
solve();
}
}