杭电第七场

时间:2022-08-10
本文章向大家介绍杭电第七场,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

存一下代码

1006

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll f[100][100][2];
ll mod=1000000007; 
//无前导0
//f[i][j][0]表示前i位0到999有j个d的方案数
//f[i][j][1]表示前i位0到123有j个d的方案数


//g[i][j][0][0]表示前i位0到999
//g[i][j][0][1]表示前i位000到999
//g[i][j][1][0]表示前i位0到123
//g[i][j][1][1]表示前i位000到123

ll read()
{
    ll x;scanf("%lld",&x);return x;
}
ll quick(ll a,ll b)
{
    ll t=1;
    for(;b;b>>=1,a=a*a%mod)
        if(b&1)t=t*a%mod;
    return t%mod;
}

ll k,B,d,now,maxi,ans;
ll g[100][100][2][2];
ll ask(ll x)
{
    ll maxi=1;
    if(d==1)
    {
        memset(g,0,sizeof(g));
        now=x%B
        g[1][0][0][0]=g[1][0][0][1]=B-1;
        g[1][0][1][0]=g[1][0][1][1]=now;
        g[1][1][0][1]=g[1][1][0][0]=g[1][1][1][0]=g[1][1][1][1]=1;
        x=x/B;
        for(int i=2;x;i++,x=x/B)
        {
            maxi=i;
            now=x%B+1;
            for(int j=0;j<=i;j++)
                g[i][j][0][0]=(g[i-1][j][0][0]+(B-1)*g[i-1][j][0][1])%mod;
            g[i][0][0][1]=((B-1)*g[i-1][0][0][1])%mod;
            for(int j=1;j<=i;j++)
                g[i][j][0][1]=(g[i-1][j-1][0][1]+(B-1)*g[i-1][j][0][1])%mod;
            if(now==1)
            {
                for(int j=0;j<=i;j++)
                    g[i][j][1][0]=g[i-1][j][1][0];
                for(int j=1;j<=i;j++)
                    g[i][j][1][1]=g[i-1][j-1][1][1];
            }
            else
            {    
                for(int j=0;j<=i;j++)
                    g[i][j][1][0]=(g[i-1][j][0][0]+(now-2)*g[i-1][j][0][1]+g[i-1][j][1][1] )%mod;
                g[i][0][1][1]=((now-2)*g[i-1][0][0][1]+g[i-1][0][1][1])%mod;
                for(int j=1;j<=i;j++)
                    g[i][j][1][1]=(g[i-1][j-1][0][1]+(now-2)*g[i-1][j][0][1]+g[i-1][j][1][1])%mod;
            }
        }
        ans=0;
        for(int i=1;i<=64;i++)
            ans=(ans+g[maxi][i][1][0]*quick(i,k)%mod)%mod;
        return ans;
    }
    memset(f,0,sizeof(f));
    
    maxi=1;
    f[1][0][0]=B-1;
    f[1][1][0]=1;
    now=x%B+1;
    if(now>=d)
        f[1][0][1]=now-1,f[1][1][1]=1;
    else
        f[1][0][1]=now,f[1][1][1]=0;
    x=x/B;
    for(int i=2;x;i++,x=x/B)
    {
        maxi=i;
        now=x%B+1; 
        f[i][0][0]=f[i-1][0][0]*(B-1)%mod;
        for(int j=1;j<=i;j++)
            f[i][j][0]=(f[i-1][j][0]*(B-1)%mod+f[i-1][j-1][0])%mod;
        if(now>d)
        {
            f[i][0][1]=(f[i-1][0][0]*(now-2)%mod+f[i-1][0][1])%mod;
            for(int j=1;j<=i;j++)
                f[i][j][1]=(f[i-1][j][0]*(now-2)%mod+f[i-1][j-1][0]+f[i-1][j][1])%mod; //1带上限
        }
        else if(now==d)
        {
            f[i][0][1]=f[i-1][0][0]*(now-1)%mod;
            for(int j=1;j<=i;j++)
                f[i][j][1]=(f[i-1][j][0]*(now-1)%mod+f[i-1][j-1][1])%mod; //1带上限
        }
        else
        {
            for(int j=0;j<=i;j++)
                f[i][j][1]=(f[i-1][j][0]*(now-1)%mod+f[i-1][j][1])%mod;
        }

    }
    ans=0;
    for(int i=1;i<=maxi;i++)
            ans=(ans+f[maxi][i][1]*quick(i,k)%mod)%mod;
    return ans;
}

void work()
{
    ll l,r;
    k=read();B=read();d=read();l=read();r=read();
    d++;
    printf("%lld\n",(ask(r)-ask(l-1)+mod)%mod);
}
int main()
{
    freopen("1006.in","r",stdin); 
    for(int t=read();t;t--)
        work();
}
1006

原文地址:https://www.cnblogs.com/qywyt/p/16573566.html