51nod 算法马拉松17(告别奥运)B 分解 51nod 算法马拉松17(告别奥运)B 分解
题意 :给出一个
n
,问
想法
观察
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int mod = 1e9 + 7;
int t = 2;
struct mat
{
long long v[maxn][maxn];
int n;
void clear()
{
n = t;
memset(v, 0, sizeof(v));
}
void unit()
{
clear();
for(int i=0; i<n; i++)
v[i][i] = 1;
}
void fro()
{
clear();
v[0][1] = v[1][0] = v[1][1] = 1;
}
void print()
{
for(int i=0; i<n; i++)
{
cout << v[i][0];
for(int j=1; j<n; j++)
cout << " " << v[i][j];
cout << endl;
}
}
};
mat operator * (const mat a, const mat b)
{
mat res;
res.clear();
for(int i=0; i<t; i++)
{
for(int j=0; j<t; j++)
{
for(int k=0; k<t; k++)
{
res.v[i][j] = (res.v[i][j] + a.v[i][k] * b.v[k][j]) % mod;
}
}
}
return res;
}
mat operator ^ (mat a, long long b)
{
mat r , base = a;
r.unit();
while(b)
{
if(b&1)
r = r * base;
base = base * base;
b >>= 1;
}
return r;
}
int main()
{
long long m;
mat a;
a.clear();
a.v[0][0] = 1, a.v[0][1] = 1;
a.v[1][0] = 2, a.v[1][1] = 1;
cin >> m;
if(m == 0) {
cout << 1 << endl; return 0;
} else if(m == 1) {
cout << 2 << endl; return 0;
}
a = (a^(m-1));
long long t = a.v[0][0] + a.v[1][0];
long long s = a.v[0][1] + a.v[1][1];
long long tm = (t % mod) * (t % mod) % mod;
long long sm = ((s % mod) * (s % mod) * 2 + 1 )% mod;
long long ms = ((s % mod) * (s % mod) * 2 - 1 + mod)% mod;
if(tm == sm)
cout << tm << endl;
else if(tm == ms)
cout << (tm + 1 + mod) % mod << endl;
else
cout << "no" << endl;
return 0;
}