A Short problemTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2333 Accepted Submission(s): 817
Problem Description
According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
Hence they prefer problems short, too. Here is a short one: Given n (1 <= n <= 1018), You should solve for where
Input
There are several test cases. For each test case there is an integer n in a single line.
Please process until EOF (End Of File).
Output
For each test case, please print a single line with a integer, the corresponding answer to this case.
Sample Input
Sample Output
|
题意不说了。。。
思路:打表找出每一层循环节,然后矩阵快速幂。
打表找循环节代码:
#include <cstdio>
#define LL long long
#define MOD1 1000000007
#define MOD2 222222224
#define MOD3 183120
int main()
{
LL x = 0, y = 1;
for(int i = 1; ; i++)
{
LL x1 = 3*y%MOD2 + x;
x1 %= MOD2;
x = y, y = x1;
if(x == 0 && y == 1)
{
printf("%d\n", i);
break;
}
}
return 0;
}
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define MOD1 1000000007
#define MOD2 222222224
#define MOD3 183120
using namespace std;
struct Matrix
{
LL a[3][3];
};
Matrix ori, res;
void init()
{
memset(ori.a, 0, sizeof(ori.a));
memset(res.a, 0, sizeof(res.a));
ori.a[0][1] = ori.a[1][0] = 1;
ori.a[1][1] = 3;
for(int i = 0; i < 2; i++)
res.a[i][i] = 1;
}
Matrix muitl(Matrix x, Matrix y, LL M)
{
Matrix z;
memset(z.a, 0, sizeof(z.a));
for(int i = 0; i < 2; i++)
{
for(int k = 0; k < 2; k++)
{
if(x.a[i][k] == 0) continue;
for(int j = 0; j < 2; j++)
z.a[i][j] = (z.a[i][j] + (x.a[i][k] * y.a[k][j]) % M) % M;
}
}
return z;
}
LL ans, F[3];
LL solve(LL n, LL M)
{
if(n <= 1)
return n;
init();
n -= 1;//自减一
while(n)
{
if(n & 1)
res = muitl(ori, res, M);
ori = muitl(ori, ori, M);
n >>= 1;
}
return F[1] * res.a[1][1] % M;
}
int main()
{
F[0] = 0, F[1] = 1;
LL N;
while(scanf("%lld", &N) != EOF)
{
ans = solve(N, MOD3);//最里层
ans = solve(ans, MOD2);//第二层
ans = solve(ans, MOD1);//最外层
printf("%lld\n", ans);
}
return 0;
}