# 【xdoj难题集】1228 敬老师的手环1

# include <cstdio>
# include <cstring>

const int Mod = 1e9 + 7;
const int MAX_N = 1e4;

typedef long long ll;

int N;
int box[MAX_N];
int num;
int st[MAX_N];
int top;

namespace juzhen
{
typedef int mtype;
typedef long long ll;

const int MAX_N = 2;
const int Mod = 1e9 + 7;

int N = MAX_N;
int M = MAX_N;
int K = MAX_N;

void mul(mtype (&A)[MAX_N][MAX_N] , mtype (&B)[MAX_N][MAX_N] , mtype (&C)[MAX_N][MAX_N])
{
mtype D[MAX_N][MAX_N] = {0};

int i, k, j;
for(i = 0 ; i < N ; i++)
for(k = 0 ; k < M ; k++)
for(j = 0 ; j < K ; j++)
D[i][j] = (D[i][j] + (ll)A[i][k] * B[k][j]) % Mod;

memcpy(C , D , sizeof(C));
}

void pow(mtype (&A)[MAX_N][MAX_N] , mtype (&C)[MAX_N][MAX_N] , ll n)
{
mtype B[MAX_N][MAX_N] = {0};

int i;
for(i = 0 ; i < N ; i++)
B[i][i] = 1;

while(n)
{
if(n & 1)
mul(A , B , B);

n >>= 1;
mul(A , A , A);
}

memcpy(C , B , sizeof(C));
}

mtype fib(int n)
{
mtype A[MAX_N][MAX_N];
A[0][0] = 1;
A[0][1] = 1;
A[1][0] = 1;
A[1][1] = 0;

pow(A , A , n + 1);
return A[0][1];
}
}

int po(int a , ll b , int mo)
{
int ans = 1;
while(b)
{
if(b & 1)
ans = (ll)ans * a % mo;

b >>= 1;
a = (ll)a * a % mo;
}

return ans;
}

void div(int n)
{
num = top = 0;
box[num++] = 1;

int i, j;
for(i = 2 ; (ll)i * i <= n ; i++)
{
if(n % i == 0)
{
int siz = num;
st[top++] = i;

while(n % i == 0)
{
n /= i;
for(j = 0 ; j < siz ; j++)
{
box[num] = box[num - siz] * i;
num++;
}
}
}
}

if(n - 1)
{
int siz = num;
st[top++] = n;
for(j = 0 ; j < siz ; j++)
{
box[num] = box[num - siz] * n;
num++;
}
}
}

void solve()
{
div(N);

int i, j;
ll res = 0;

for(i = 0 ; i < num ; i++)
{
ll euler = box[i];
for(j = 0 ; j < top ; j++)
{
if(box[i] % st[j] == 0)
euler = euler / st[j] * (st[j] - 1);
}

int x = N / box[i];

ll sum = x % 2 ? 0 : 2;
//printf("%d\n", x);
sum += juzhen::fib(x) + juzhen::fib(x - 2);

res += euler % Mod * sum % Mod;
res %= Mod;
}

printf("%lld\n", res * po(N , Mod - 2 , Mod) % Mod);
}

int main()
{
while(~scanf("%d", &N))
solve();

return 0;
}


• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120