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

    题目链接:点击传送

    吉哥系列故事——恨7不成妻

    Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)


    Problem Description
      单身!
      依然单身!
      吉哥依然单身!
      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 求模后输出。
     
    Sample Input
    3 1 9 10 11 17 17
     
    Sample Output
    236 221 0
     
    Source
    思路:
    dp[mod][sum][k]表示在pos的位置前面数字对7取模,前面数字之和对7取模,前面是否出现过7;
    为什么不能直接返回s*s呢,因为你的标记是mod,sum,k;两个数前面的那部分可能会使得mod,sum,k相等,比如,07,跟70;
    然后一个数的平方利用开方来处理;
    详见代码。
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define pi (4*atan(1.0))
    #define eps 1e-4
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=2e3+10,M=9e3+10,inf=2147483647;
    const ll INF=1e18+10,mod=1e9+7;
    struct nsq
    {
        ll num,sum,sqsum;
        nsq(){}
        nsq(ll a,ll b,ll c)
        {
            num=a,sum=b,sqsum=c;
        }
    };
    nsq f[20][10][10][3];
    ll bit[20];
    ll qpow(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)ans=(ans*a)%mod;
            b>>=1;
            a=(a*a)%mod;
        }
        return ans;
    }
    ll qmul(ll a,ll b)
    {
        ll ans=0;
        while(b)
        {
            if(b&1)ans=(ans+a)%mod;
            b>>=1;
            a=(a+a)%mod;
        }
        return ans;
    }
    ll add(ll a,ll b)
    {
        return (a+b)%mod;
    }
    ll del(ll a,ll b)
    {
        return ((a-b)%mod+mod)%mod;
    }
    nsq dp(int pos,int sum,int mod,int k,int flag)
    {
        if(pos==0)return nsq(sum&&mod&&!k,0,0);
        if(flag&&f[pos][sum][mod][k].num!=-1)return f[pos][sum][mod][k];
        int x=flag?9:bit[pos];
        nsq ans(0,0,0);
        for(int i=0;i<=x;i++)
        {
            nsq nnnn=dp(pos-1,(sum+i)%7,(mod*10+i)%7,k||i==7,flag||i<x);
            ans.num=add(ans.num,nnnn.num);
            ans.sum=add(ans.sum,add(nnnn.sum,qmul(nnnn.num,qmul(1LL*i,qpow(10,pos-1)))));
            ans.sqsum=add(ans.sqsum,add(nnnn.sqsum,qmul(nnnn.num,qmul(1LL*i*i,qpow(10,2*pos-2)))));
            ans.sqsum=add(ans.sqsum,qmul(nnnn.sum,qmul(2LL*i,qpow(10,pos-1))));
        }
        if(flag)f[pos][sum][mod][k]=ans;
        return ans;
    }
    nsq getans(ll x)
    {
        int len=0;
        while(x)
        {
            bit[++len]=x%10;
            x/=10;
        }
        return dp(len,0,0,0,0);
    }
    int main()
    {
        int T,cas=1;
        memset(f,-1,sizeof(f));
        scanf("%d",&T);
        while(T--)
        {
            ll l,r;
            scanf("%lld%lld",&l,&r);
            printf("%lld
    ",del(getans(r).sqsum,getans(l-1).sqsum));
        }
        return 0;
    }

    吉哥系列故事——恨7不成妻

    Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 3846    Accepted Submission(s): 1230


    Problem Description
      单身!
      依然单身!
      吉哥依然单身!
      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 求模后输出。
     
    Sample Input
    3 1 9 10 11 17 17
     
    Sample Output
    236 221 0
     
    Source
  • 相关阅读:
    mysql修改加密方式
    信息安全学习路线
    DNS域传送漏洞
    CSRF漏洞
    反序列化漏洞
    计算机通讯基础
    gorm gen使用
    golang makefile使用
    linux命令行录制
    go代码自动生成注释
  • 原文地址:https://www.cnblogs.com/jhz033/p/6613355.html
Copyright © 2011-2022 走看看