Description
Will有一个神秘盒,传说只要有人能解开神秘盒上的密码,就可以预知未来(比如知道这道题的标程是怎样的),你愿意来尝试一下么?
Input
从文件passw.in中读入数据。
输入仅包含一行一个整数N。
Output
输出到文件passw.out中。
输出仅包含一行一个整数f(N)。
Sample Input
2
Sample Output
35
Data Constraint
对于10%的数据满足
N
≤
4
N ≤ 4
N≤4;
对于30%的数据满足
N
≤
12
N ≤ 12
N≤12;
对于60%的数据满足
N
≤
1
0
5
N ≤ 10^5
N≤105;
对于100%的数据满足
3
≤
N
≤
1
0
18
3 ≤ N ≤ 10^{18}
3≤N≤1018。
Hint
SN={1, 2, 11},故f(N)=1×2+1×11+2×11=35。
分析:
设
a
=
∑
x
∈
S
N
x
a=\sum_{x\in S_N}x
a=∑x∈SNx,
b
=
∑
x
∈
S
N
x
2
b=\sum_{x\in S_N}x^2
b=∑x∈SNx2。
答案就是
(
a
2
−
b
)
/
2
(a^2-b)/2
(a2−b)/2。
关键求
a
a
a和
b
b
b。
考虑dp,设
f
[
i
]
f[i]
f[i]表示所有位置数字和为
i
i
i的数的个数,
g
[
i
]
g[i]
g[i]表示所有位置数字和为
i
i
i的数的和,
h
[
i
]
h[i]
h[i]表示所有位置数字和为
i
i
i的数的平方和。
考虑在每个数的最右边加一个数字。有
f
[
i
]
=
f
[
i
−
1
]
+
f
[
i
−
2
]
+
.
.
.
+
f
[
i
−
9
]
f[i]=f[i-1]+f[i-2]+...+f[i-9]
f[i]=f[i−1]+f[i−2]+...+f[i−9]
g
[
i
]
=
(
g
[
i
−
1
]
∗
10
+
1
∗
f
[
i
−
1
]
)
+
(
g
[
i
−
2
]
∗
10
+
f
[
i
−
2
]
∗
2
)
+
.
.
.
g[i]=(g[i-1]*10+1*f[i-1])+(g[i-2]*10+f[i-2]*2)+...
g[i]=(g[i−1]∗10+1∗f[i−1])+(g[i−2]∗10+f[i−2]∗2)+...
h
[
i
]
=
(
h
[
i
−
1
]
∗
100
+
2
∗
10
∗
g
[
i
−
1
]
+
f
[
i
−
1
]
∗
1
2
)
+
(
h
[
i
−
2
]
∗
100
+
2
∗
20
∗
g
[
i
−
2
]
+
f
[
i
−
2
]
∗
2
2
)
h[i]=(h[i-1]*100+2*10*g[i-1]+f[i-1]*1^2)+(h[i-2]*100+2*20*g[i-2]+f[i-2]*2^2)
h[i]=(h[i−1]∗100+2∗10∗g[i−1]+f[i−1]∗12)+(h[i−2]∗100+2∗20∗g[i−2]+f[i−2]∗22)
对
g
g
g和
h
h
h求和就是
a
a
a和
b
b
b。
可以矩阵乘法加速,矩阵是
29
∗
29
29*29
29∗29的。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#define LL long long
const LL mod=1000003;
const LL inv2=500002;
using namespace std;
LL n,ans;
struct matrix{
int n,m;
LL a[30][30];
}A,B,C;
matrix operator *(matrix a,matrix b)
{
matrix c;
c.n=a.n,c.m=b.m;
for (int i=0;i<=c.n;i++)
{
for (int j=0;j<=c.m;j++) c.a[i][j]=0;
}
for (int k=1;k<=a.m;k++)
{
for (int i=1;i<=a.n;i++)
{
for (int j=1;j<=b.m;j++)
{
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
}
}
}
return c;
}
void power(LL k)
{
if (k==1)
{
B=A;
return;
}
power(k/2);
B=B*B;
if (k&1) B=B*A;
}
int main()
{
scanf("%lld",&n);
A.n=29,A.m=29;
for (int i=1;i<=9;i++) A.a[i][1]=1;
for (int i=2;i<=9;i++) A.a[i-1][i]=1;
for (int i=1;i<=9;i++) A.a[i][10]=i;
for (int i=10;i<=18;i++) A.a[i][10]=10;
for (int i=11;i<=18;i++) A.a[i-1][i]=1;
for (int i=1;i<=9;i++) A.a[i][19]=i*i;
for (int i=10;i<=18;i++) A.a[i][19]=2*(i-9)*10;
for (int i=19;i<=27;i++) A.a[i][19]=100;
for (int i=20;i<=27;i++) A.a[i-1][i]=1;
A.a[10][28]=1,A.a[28][28]=1;
A.a[19][29]=1,A.a[29][29]=1;
power(n+1);
C.n=1,C.m=29;
C.a[1][1]=1;
C=C*B;
ans=(C.a[1][28]*C.a[1][28]%mod+mod-C.a[1][29])%mod*inv2%mod;
printf("%lld\n",ans);
}