解题思路
对于
k
k
k 进制大数的第
i
i
i 位,当且仅当
r
∈
[
i
,
n
]
r\in [i,n]
r∈[i,n] 的时候会产生贡献,同样可以得出,对于任意
l
∈
[
1
,
r
]
l\in [1,r]
l∈[1,r],第
i
i
i 位会产生
i
i
i 次贡献,每次对答案的贡献是
a
i
×
k
r
−
i
a_i\times k^{r-i}
ai×kr−i。由此,我们对于
k
k
k 的幂次求前缀和,设得到的数组为
s
u
m
sum
sum,那么有
s
u
m
i
=
1
+
k
+
k
2
+
k
3
+
⋯
+
k
i
−
1
sum_i=1+k+k^2+k^3+\dots +k^{i-1}
sumi=1+k+k2+k3+⋯+ki−1,所以最终十进制下的答案为
∑
i
=
1
n
a
i
×
s
u
m
n
−
r
+
1
×
i
\sum_{i=1}^n a_i\times sum_{n-r+1}\times i
i=1∑nai×sumn−r+1×i
对这个答案对 m o d mod mod 取模后转化为 k k k 进制输出即可,注意特判为 0 0 0 的情况。
AC 代码
#include<stdio.h>
#include<stdlib.h>
#define N 1000005
#define Mod 20070720
#define int long long
int n,k,a[N],ans[N],m,Mi[N];
inline void work(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;++i)
scanf("%lld",&a[i]);
for(int i=1;i<=n;++i) a[i]%=Mod;
Mi[0]=1; int sum=0; m=0;
for(int i=1;i<=n;++i)
Mi[i]=Mi[i-1]*k%Mod;
for(int i=1;i<=n;++i)
(Mi[i]+=Mi[i-1])%=Mod;
for(int i=1;i<=n;++i)
(sum+=i*Mi[n-i]%Mod*a[i]%Mod)%=Mod;
while(sum) ans[++m]=sum%k,sum/=k;
while(ans[m]==0&&m) --m;
if(m==0) return puts("0"),void();
for(int i=m;i>=1;--i)
printf("%lld ",ans[i]);
putchar('\n');
}
signed main(){
int T;scanf("%lld",&T);
while(T--) work();
system("pause");
}