Description
Will有一个神秘盒,传说只要有人能解开神秘盒上的密码,就可以预知未来(比如知道这道题的标程是怎样的),你愿意来尝试一下么?
Input
从文件passw.in中读入数据。
输入仅包含一行一个整数N。
Output
输出到文件passw.out中。
输出仅包含一行一个整数f(N)。
Sample Input
2
Sample Output
35
Data Constraint
对于10%的数据满足 N≤4N ≤ 4N≤4;
对于30%的数据满足 N≤12N ≤ 12N≤12;
对于60%的数据满足 N≤105N ≤ 10^5N≤105;
对于100%的数据满足 3≤N≤10183 ≤ N ≤ 10^{18}3≤N≤1018。
Hint
SN={1, 2, 11},故f(N)=1×2+1×11+2×11=35。
分析:
设a=∑x∈SNxa=\sum_{x\in S_N}xa=∑x∈SNx,b=∑x∈SNx2b=\sum_{x\in S_N}x^2b=∑x∈SNx2。
答案就是(a2−b)/2(a^2-b)/2(a2−b)/2。
关键求aaa和bbb。
考虑dp,设f[i]f[i]f[i]表示所有位置数字和为iii的数的个数,g[i]g[i]g[i]表示所有位置数字和为iii的数的和,h[i]h[i]h[i]表示所有位置数字和为iii的数的平方和。
考虑在每个数的最右边加一个数字。有
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]∗12)+(h[i−2]∗100+2∗20∗g[i−2]+f[i−2]∗22)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)
对ggg和hhh求和就是aaa和bbb。
可以矩阵乘法加速,矩阵是29∗2929*2929∗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);
}