题解 P5257 【密码 】

· · 题解

蒟乘

答案很明显是\ \frac{(\sum x)^2-\sum x^2}{2}

设$f[i]$为$G(N)=i$的$N$的**个数**,$g[i]$为$G(N)=i$的$N$的**和**,$h[i]$为$G(N)=i$的$N$的**平方和**。 $$f[i]=\sum_{j=1}^9f[i-j]$$ $$g[i]=\sum_{j=1}^910\times g[i-j]+j\times f[i-j]$$ $$h[i]=\sum_{j=1}^9100\times h[i-j]+20j\times g[i-j]+j^2\times f[i-j]$$ 放在一个矩阵里转移就好了 $$\text{答案是}\ \frac{(\sum_{i=1}^ng[i])^2-\sum_{i=1}^nh[i]}{2}$$ ```cpp #include<cstdio> #include<cstring> const int mod=1e6+3; struct mat{ int c[30][30]; void clear(){memset(c,0,sizeof(c));} mat operator *(const mat &o)const{ mat r; r.clear(); for(int i=1;i<=29;i++) for(int k=1;k<=29;k++) for(int j=1;j<=29;j++) if(c[i][k]&&o.c[k][j]) r.c[i][j]=(r.c[i][j]+1ll*c[i][k]*o.c[k][j])%mod; return r; } }f,g; int ksm(int u,int v){ int res=1; for(;v;v>>=1,u=1ll*u*u%mod) if(v&1)res=1ll*res*u%mod; return res; } typedef long long LL; LL n; int main(){ scanf("%lld",&n); f.c[1][9]=1;//f[0]=1 for(int i=1;i<=8;i++)g.c[i+1][i]=1; for(int i=1;i<=9;i++)g.c[i][9]=1; for(int i=10;i<=17;i++)g.c[i+1][i]=1; for(int i=1;i<=9;i++)g.c[i][18]=10-i; for(int i=10;i<=18;i++)g.c[i][18]=10; for(int i=19;i<=26;i++)g.c[i+1][i]=1; for(int i=1;i<=9;i++)g.c[i][27]=(10-i)*(10-i); for(int i=10;i<=18;i++)g.c[i][27]=(19-i)*20; for(int i=19;i<=27;i++)g.c[i][27]=100; g.c[18][28]=g.c[28][28]=1; g.c[27][29]=g.c[29][29]=1; //我这里求的是n-1的\sum,所以n要加1 for(++n;n;n>>=1,g=g*g) if(n&1)f=f*g; printf("%lld\n",1ll*(1ll*f.c[1][28]*f.c[1][28]-f.c[1][29]+mod)%mod*ksm(2,mod-2)%mod); } ```