[BZOJ 3326] 数数

Link:

BZOJ 3326 传送门

Solution:

明显是一道数位$dp$的题目,就是递推式复杂了点

先要求出一个数$\bar{n}$向添加一位后的$\bar{np}$的转化关系

 

令$res[\bar{n}]$为数$n$的权值和,

则$res[\bar{np}]=res[\bar{n}]+\sum_{i=1}^{len(n)} \bar{n[i...len(n)]p}$

令$suf[\bar{n}]$为数$n$的后缀和,

则$res[\bar{np}]=res[\bar{n}]+suf[\bar{np}]$

同时$suf$自己的递推式为:$suf[\bar{np}]=base*suf[\bar{n}]+(len(n)+1)*p$

再令$dgt[\bar{n}]$为数$n$的位数,

则$dgt[\bar{np}]=dgt[\bar{n}]+1$

 

上面的递推式虽然都只针对某一个数$n$,但完全可以逐层推广到之前所有数的和

使原来的$res,suf,dgt$分别表示$\sum res,\sum suf,\sum dgt$,$a$表示数的个数

再用第二维的$0/1$表示是否达到上界,算是数位$dp$的常规套路

剩下的递归式还是看代码吧……

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=1e5+10,MOD=20130427;

int B,l1,l2,dat1[MAXN],dat2[MAXN];
ll pre[MAXN],res[MAXN][2],a[MAXN][2],suf[MAXN][2],dgt[MAXN][2];

ll solve(int *dat,int l)
{
    memset(res,0,sizeof(res));memset(dgt,0,sizeof(dgt));
    memset(a,0,sizeof(a));memset(suf,0,sizeof(suf));
    
    a[l+1][0]=1;
    for(int i=l;i;i--)
    {
        int cur=(i==l)?0:B;
        
        a[i][0]=a[i+1][0];
        a[i][1]=((cur-1)+a[i+1][1]*B+a[i+1][0]*dat[i])%MOD;
        dgt[i][0]=(dgt[i+1][0]+a[i+1][0])%MOD;
        dgt[i][1]=((cur-1)+(dgt[i+1][1]+a[i+1][1])*B%MOD+(dgt[i+1][0]+a[i+1][0])*dat[i]%MOD)%MOD;
        suf[i][0]=(suf[i+1][0]*B+dgt[i][0]*dat[i])%MOD;
        suf[i][1]=(pre[cur]+(suf[i+1][1]*B%MOD*B%MOD+(dgt[i+1][1]+a[i+1][1])*pre[B]%MOD)+
                   (suf[i+1][0]*B*dat[i]%MOD+dgt[i][0]*pre[dat[i]]%MOD))%MOD;
        res[i][0]=(res[i+1][0]+suf[i][0])%MOD;
        res[i][1]=(res[i+1][0]*dat[i]%MOD+res[i+1][1]*B%MOD+suf[i][1])%MOD;
    }
    return (res[1][0]+res[1][1])%MOD;
}

int main()
{
    scanf("%d",&B);
    for(int i=1;i<=B;i++) pre[i]=(pre[i-1]+i-1)%MOD;
    
    scanf("%d",&l1);
    for(int i=l1;i>=1;i--) scanf("%d",&dat1[i]);
    scanf("%d",&l2);
    for(int i=l2;i>=1;i--) scanf("%d",&dat2[i]);
    
    for(int i=1;i<=l1;i++)
        if(dat1[i]){dat1[i]--;break;}
        else dat1[i]=B-1;
    if(!dat1[l1]) l1--;
    
    printf("%lld",(solve(dat2,l2)-solve(dat1,l1)+MOD)%MOD);
    return 0;
}

 

posted @ 2018-07-17 17:35  NewErA  阅读(247)  评论(0编辑  收藏  举报