题目描述
Consider digits strings with length n, how many different strings have the sum of digits are multiple of 4?
输入描述:
There are several test cases end with EOF. For each test case, there is an integer in one line: n, the length of the digits string. (1≤n≤1,000,000,000).
输出描述:
For each case, output the number of digits strings with length n have the sum of digits are multiple of 4 in one line. The numbers maybe very large, you should output the result modular 2019.
输入
1
2
3
4
输出
3
25
249
479
思路
长度为1有四种情况:
- %4 == 0 有3个
- %4 == 1 有3个
- %4 == 2 有2个
- %4 == 3 有2个
计算长度为N的分为四种情况:
令长度为N-1模4为{0, 1, 2, 3}的数量为T0, T1, T3, T4
- %4 == 0
(%4=0) * T0 + (%4=1) * T3 + (%4=2) * T2 + (%4=3) * T1 - %4 == 1
(%4=0) * T1 + (%4=1) * T0 + (%4=2) * T3 + (%4=3) * T2 - %4 == 2
- (%4=0) * T2 + (%4=1) * T1 + (%4=2) * T0 + (%4=3) * T3
- %4 == 3
(%4=0) * T3 + (%4=1) * T2 + (%4=2) * T1 + (%4=3) * T0
根据这个思路可以用矩阵快速幂加快一下
#include <bits/stdc++.h>
#define LL long long
#define P pair<int, int>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define REP(i, n) for (int i = 1; i <= (n); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define N 100005
using namespace std;
void mul(LL x[], LL y[]) {
LL t[4];
t[0] = x[0] * y[0] + x[1] * y[3] + x[3] * y[1] + x[2] * y[2];
t[1] = x[1] * y[0] + x[0] * y[1] + x[2] * y[3] + x[3] * y[2];
t[2] = x[0] * y[2] + x[2] * y[0] + x[1] * y[1] + x[3] * y[3];
t[3] = x[0] * y[3] + x[3] * y[0] + x[1] * y[2] + x[2] * y[1];
rep (i, 4) x[i] = t[i] % 2019;
}
LL quick(LL x) {
LL b[4] = {3, 3, 2, 2};
LL a[4] = {3, 3, 2, 2};
while (x) {
if (x & 1) mul(a, b);
mul(b, b);
x >>= 1;
}
return a[0];
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
LL n;
while (scanf("%lld", &n) != EOF) {
LL ans = quick(n-1);
printf("%d\n", ans % 2019);
}
return 0;
}