题解:P10791 『SpOI - R1』强大到让你们所有人注视

解题思路

对于 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×kri。由此,我们对于 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++ki1,所以最终十进制下的答案为
∑ 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=1nai×sumnr+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");
}
  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值