• 恨7不成妻(暑假D8 T3)


    题目描述

    单身! 
    依然单身! 
    吉哥依然单身! 
    DS级码农吉哥依然单身! 
    所以,他生平最恨情人节,不管是214还是77,他都讨厌! 
       
    吉哥观察了214和77这两个数,发现: 
    2+1+4=7 
    7+7=7*2 
    77=7*11 
    最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数! 

    什么样的数和7有关呢? 

    如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关—— 
    1、整数中某一位是7; 
    2、整数的每一位加起来的和是7的整数倍; 
    3、这个整数是7的整数倍; 

    现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。 

    Input

    输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。

    Output

    请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。

    题解

    按照最普通的想法,f[pos][x][sum]记为当前在pos位置,现在的数mod7,数位和mod7

    但要想记忆化搜索,还需要记下当前的ans:平方和,这是1e9+7的,肯定不行。

    于是有了一种神仙做法,开结构体,还是上面的定义,在结构体中记录当前与7无关的数的个数cnt,这些与7无关的数的和sum(只记录[1,pos-1]这一段),这些数的平方和pow(也只记录那一段)

    记录当前答案rt,当当前位填i时得到答案tmp

    rt.cnt+=tmp.cnt

    rt.sum+=tmp.sum+i*pow10[pos-1]*tmp.cnt;  因为后面有tmp.cnt种填法,那么填了tmp.cnt次,而且每一次的贡献为i*pow10[pos-1]

    记i*pow10[pos-1]为x,后面某种填法得到的一段为y,得到新的一段的平方(x+y)2=(x2+2*x*y+y2

    对于每个y都这样计算,加起来会得到 tmp.cnt*x2+2*x*tmp.sum+tmp.pow,rt.pow+=这个值

    为了方便书写,记pow10[1]=1,注意多%

    #include<bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    const int mod=1000000007;
    int t;
    ll l,r,pow10[25];
    ll len,num[20];
    ll ans;
    struct gdpl{
        ll cnt,sum,pow;//此时与七无关的数的个数,和,平方和(后面一段数位) 
        gdpl(){cnt=-1;pow=sum=0;}
        gdpl(ll cnt,ll sum,ll pow) : cnt(cnt),sum(sum),pow(pow){}
    }f[20][8][8];
    
    template<class T>inline void read(T &x){
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    gdpl dfs(int s,int  x,int sum,bool lim){
        if(!s) return x&&sum ? gdpl(1,0,0) : gdpl(0,0,0);
        if(!lim&&f[s][x][sum].cnt!=-1) return f[s][x][sum];
        int mx=lim ? num[s] : 9 ;
        gdpl rt(0,0,0);
        for(int i=0;i<=mx;i++){
            if(i==7) continue;
            gdpl tmp=dfs(s-1,(10*x+i)%7,(sum+i)%7,lim&&i==mx);
            rt.cnt=(rt.cnt + tmp.cnt )%mod;
            rt.sum=(rt.sum + tmp.sum + i * pow10[s] % mod * tmp.cnt % mod )%mod;
            rt.pow=(rt.pow + tmp.pow + 2 * pow10[s] % mod * i%mod * tmp.sum % mod )%mod;
            rt.pow=(rt.pow + tmp.cnt * pow10[s] % mod * pow10[s] % mod * i * i % mod )%mod;
        }
        if(!lim) f[s][x][sum]=rt;
        return rt;
    }
    
    ll cx(ll x){
        len=0;
        while(x){
            num[++len]=x%10;
            x/=10;
        }
        return dfs(len,0,0,true).pow;
    }
    
    inline void nice(){
        read(l);read(r);
        printf("%lld
    ",((cx(r)-cx(l-1))%mod+mod)%mod);
    }
    
    int main(){
        pow10[1]=1;
        for(int i=2;i<=20;i++) pow10[i]=pow10[i-1]*10%mod;
        read(t);
        while(t--) nice();
    }
    View Code
  • 相关阅读:
    caffe:mac10.12安装caffe的步骤
    查找两个链表的共同子链表
    golang:1.并发编程之互斥锁、读写锁详解
    git问题汇总
    有用的技术工具
    maven 安装本地jar包到本地maven仓库
    win7下Hadoop学习 之 Cygwin下载、安装、配置
    简单目录备份脚本
    2021年01月28日微博热搜汇总
    2021年01月26日微博热搜汇总
  • 原文地址:https://www.cnblogs.com/sto324/p/11203737.html
Copyright © 2020-2023  润新知