【NOIP2016提高A组模拟9.24】我的快乐时代

55 篇文章 0 订阅
44 篇文章 0 订阅

Description

这里写图片描述

Input

一行,两个整数l,r 。

Output

一行,一个整数,表示第l 天到第r 天的愉悦值的和。

Sample Input

Input 1
64 89
Input 2
3 233
Input 3
2333333333 66666666666666

Sample Output

Output 1
1818
Output 2
8730
Output 3
836269739

Data Constraint

l<=r<=1018

Solution

首先要%一发出题人的语文功底
接着%题目主人公WerKeytom_FTD
设一个get(r)表示从1到r的和
答案就是get(r)-get(l-1)
那么如何求get?
设要求得是get(n)
分为两种情况,位数=n和位数

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define mo 1000000007ll
#define fo(i,a,b) for(ll i=a;i<=b;i++)
#define fd(i,a,b) for(ll i=a;i>=b;i--)
using namespace std;
ll a[30],f[30][2],mi[30];
ll sl(ll n)
{
    ll m=0,ans=0;
    for(ll i=n;i;i/=10) a[++m]=i%10;
    fo(l,1,m-1)
    {
        if (l==1)fo(x1,1,9) ans=(ans+(((x1*x1)%mo)*max(mi[l-2],1ll))%mo)%mo;
        else fo(x1,1,9) fo(x2,1,9) ans=(ans+(((x1*x2*2ll)%mo)*max(mi[l-2],1ll))%mo)%mo;
        fo(p,2,l-1)
        {
            int q=l-p+1;
            fo(x1,1,9)
                fo(x2,1,9)
                if(p!=q||x1==x2)
                    if(p!=q) ans=(ans+(((x1*x2)%mo)*mi[l-3]*9ll)%mo)%mo;
                    else ans=(ans+(((x1*x2)%mo)*mi[l-2]*9ll)%mo)%mo;
        }
    }

    fo(p,1,m)
    {
        ll q=m-p+1;
        fo(x1,1,9)
            fo(x2,1,9)
            if(p!=q||x1==x2)
            {
                memset(f,0,sizeof(f));
                if(p!=m&&q!=m) f[m][1]=1ll,f[m][0]=a[m]-1ll;
                if(p==m)
                    if(x1<a[m]) f[m][0]=1ll,f[m][1]=0ll;
                    else if(x1==a[m]) f[m][0]=0ll,f[m][1]=1ll;
                         else continue;
                if(q==m)
                    if(x2<a[m]) f[m][0]=1ll,f[m][1]=0ll;
                    else if(x2==a[m]) f[m][0]=0ll,f[m][1]=1ll;
                         else continue;
                fd(i,m,1)
                {
                    int jy=0;if(i==m) jy=1;
                    if(i==p)
                    {
                        if(x1==a[i])f[i][1]=(f[i][1]+f[i+1][1])%mo;
                        if(x1<a[i]) f[i][0]=(f[i][0]+f[i+1][1])%mo; 
                        f[i][0]=(f[i][0]+f[i+1][0])%mo;
                    }
                    else if(i==q)
                         {
                             if(x2==a[i])f[i][1]=(f[i][1]+f[i+1][1])%mo;
                             if(x2<a[i]) f[i][0]=(f[i][0]+f[i+1][1])%mo; 
                             f[i][0]=(f[i][0]+f[i+1][0])%mo;
                         }
                         else 
                         fo(e,jy,9)
                         {
                            if(e==a[i]) f[i][1]=(f[i][1]+f[i+1][1])%mo;
                            if(e<a[i]) f[i][0]=(f[i][0]+f[i+1][1])%mo;
                            f[i][0]=(f[i][0]+f[i+1][0])%mo;
                         }
                }   
                ans=(ans+x1*x2*(f[1][0]+f[1][1]))%mo;
            }
    }
    return ans;
}
int main()
{
    mi[0]=1;fo(i,1,19) mi[i]=(mi[i-1]*10)%mo;
    ll l,r;scanf("%lld%lld",&l,&r);
    printf("%lld",(sl(r)-sl(l-1)+mo)%mo);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值