zoukankan      html  css  js  c++  java
  • HUD 4507 吉哥系列故事——恨7不成妻

    传送门

    三个限制都可以数位 $dp$ , $dfs$ 是维护当前位,之前各位总和模 $7$ 意义下的值,之前填的数模 $7$ 意义下的值,是否贴着限制

    主要现在求的是各个合法数的平方的和,比较恶心

    开一个结构体维护一下三个东西,合法数的个数,合法数的和,合法数的平方和

    前两个好维护,平方和发现其实可以拆开,比如下一层 $dfs$ 传上来的和为 $x$ ,当前位填的数为 $k$ ,考虑当前所有合法数的平方和看成每一个合法数的平方的和

    设下一层某一个合法数传上来的值为 $y$,那么当前层的值即为

    $10^p cdot k + y$ ,平方后即为 $10^{2p} cdot k^2 + y^2 + 2ky cdot 10^p$

    发现所有的 $y^2$ 加起来以后其实就是下一层的合法数的平方和

    对于 $2ky cdot 10^p$ ,把 $2k cdot 10^p$ 提出来,那么也可以把所有 $y$ 加起来即为下一层的合法数的和

    对于 $10^{2p} cdot k^2$ ,因为加了下一层合法数的个数次,那么贡献即为下一层合法数数量乘 $10^{2p} cdot k^2$

    所以我们完全可以用下一层的数据维护出当前位的数据

    具体实现可以看代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int mo=1e9+7;
    inline int fk(int x) { return x>=mo ? x-mo : x; }
    ll T,L,R;
    struct dat {
        ll tot,sum,sum2;
        dat (ll _tot=0,ll _sum=0,ll _sum2=0) { tot=_tot,sum=_sum,sum2=_sum2; }
        inline dat operator + (const dat &tmp) const {
            return dat(fk(tot+tmp.tot),fk(sum+tmp.sum),fk(sum2+tmp.sum2));
        }
        inline dat operator * (const ll &tmp) const {
            return dat(tot, fk(tot*tmp%mo + sum) , fk( fk((tot*tmp%mo)*tmp%mo + (2ll*tmp%mo)*sum%mo) + sum2 ) );
        }
    }f[19][9][9][2];
    ll Power[19];
    vector <int> V;
    dat dfs(int p,int sum,int now,bool lim)
    {
        if(!p) return (sum&&now) ? dat(1,0,0) : dat(0,0,0);
        dat &t=f[p][sum][now][lim];
        if(t.tot!=-1) return t;
        t.tot=0;
        for(int k=0;k<=9;k++)
        {
            if(lim&&k>V[p-1]) break;
            if(k==7) continue;
            dat add=dfs(p-1,(sum+k)%7,(now*10+k)%7,lim&(k==V[p-1]));
            t=t + ( add * (Power[p-1]*k%mo) );
        }
        // cout<<p<<" "<<sum<<" "<<now<<" "<<lim<<" "<<t.tot<<" "<<t.sum<<" "<<t.sum2<<endl;
        return t;
    }
    inline void Clr()
    {
        for(int i=1;i<=18;i++)
            for(int j=0;j<7;j++)
                for(int k=0;k<7;k++)
                    f[i][j][k][0]=f[i][j][k][1]=dat(-1,0,0);
    }
    int main()
    {
        T=read();
        Power[0]=1; for(int i=1;i<=18;i++) Power[i]=Power[i-1]*10%mo;
        while(T--)
        {
            L=read()-1,R=read();
            ll now=R; V.clear(); Clr();
            while(now) V.push_back(now%10),now/=10;
            ll ans=dfs(V.size(),0,0,1).sum2;
            now=L; V.clear(); Clr();
            while(now) V.push_back(now%10),now/=10;
            printf("%d
    ",fk(ans-dfs(V.size(),0,0,1).sum2+mo));
        }
        return 0;
    }
  • 相关阅读:
    C# 工厂
    sql server 数据库 数据DateTime 转mysql
    java 快捷工具,如何清理不需要的引用
    动态调用webservice 接口
    动态调用wcf接口服务
    下载图片出现问题
    jQuery Validation Engine 表单验证
    mvc5 知识点01
    mvc5 @RenderSection("scripts", required: false) 什么意思
    mvc5 _ViewStart.cshtml 模板页如何定义
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11687560.html
Copyright © 2011-2022 走看看