zoukankan      html  css  js  c++  java
  • BZOJ 1833: [ZJOI2010]count 数字计数

    Description

    问 ([L,R]) 中0-9的个数.

    Sol

    数位DP.

    预处理好长度为 (i), 最高位为 (j) 的数位之和.

    然后从上往下计算,不要忘记往下走的同时要把高位的贡献加上去..

    Code

    /**************************************************************
        Problem: 1833
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:40 ms
        Memory:1396 kb
    ****************************************************************/
     
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
     
    typedef long long LL;
    const int N = 65;
     
    struct S {
        LL a[10];
        S(LL v=0) { for(int i=0;i<10;i++) a[i]=v; }
    }f[N][10][2];
     
    S operator + (const S &a,const S &b) {
        S c;for(int i=0;i<10;i++) c.a[i]=a.a[i]+b.a[i];
        return c;
    }
    S operator - (const S &a,const S &b) {
        S c;for(int i=0;i<10;i++) c.a[i]=a.a[i]-b.a[i];
        return c;
    }
    S operator * (const S &a,const LL &b) {
        S c;for(int i=0;i<10;i++) c.a[i]=a.a[i]*b;
        return c;
    }
    void Print(const S &a) { for(int i=0;i<9;i++) cout<<a.a[i]<<" ";cout<<a.a[9]; }
     
    LL l,r;
    LL pow10[N];
     
    inline LL Pow(LL a,LL b,LL r=1) { return pow10[b]; }
    void init() {
        pow10[0]=1;
        for(int i=1;i<=15;i++) pow10[i]=pow10[i-1]*10LL;
         
        for(int i=0;i<10;i++) {
            f[1][i][0]=f[1][i][1]=f[1][i-1][0];
            f[1][i][0].a[i]+=1,f[1][i][1].a[i]+=1;
        }
        for(int l=2;l<=14;l++) {
            f[l][0][0]=f[l-1][9][0];
            f[l][0][1]=f[l-1][9][1];
            f[l][0][1].a[0]+=Pow(10,l-1);
            for(int i=1;i<10;i++) {
                f[l][i][0]=f[l][i-1][0]+f[l-1][9][1];
                f[l][i][0].a[i]+=Pow(10,l-1);
                f[l][i][1]=f[l][i-1][1]+f[l-1][9][1];
                f[l][i][1].a[i]+=Pow(10,l-1);
            }
        }
         
    //  for(int l=1;l<=5;l++) for(int i=0;i<10;i++) {
    //      cout<<l<<":"<<i<<endl;
    //      Print(f[l][i][0]),Print(f[l][i][1]);
    //      cout<<"-------------------------------"<<endl;
    //  }
    }
    S calc(LL x) {
        LL g=0,nn;S r,t;
        for(int i=13;~i;i--) {
            if(x/pow10[i]) {
                nn=(LL)(x/pow10[i])*pow10[i];
                r=r+t*nn;
                 
                t.a[x/pow10[i]]++;
                 
                r=r+f[i+1][x/pow10[i]-1][g];
                g=1;
    //          cout<<i+1<<" "<<x/pow10[i]-1<<" "<<g<<endl;
            }else {
                if(g) t.a[0]++;
            }x%=pow10[i];
    //      cout<<i<<" ";Print(r);
        }return r;
    }
    int main() {
        init();
         
        cin>>l>>r;
         
        S ans1=calc(r+1);
        S ans2=calc(l);
         
    //  Print(ans1),Print(ans2);
        Print(ans1-ans2);
        return 0;
    }
    

      

  • 相关阅读:
    python两个装饰器的运算顺序
    python中私有属性的访问
    python中的方法使用
    创业,宁愿单兵作战也不要参在拙劣的团队里继续寻觅队友
    项目经理问:为什么总是只有我在加班 – 挂包袱现象
    我该怎么安排下属的工作-项目经理如何分配任务
    项目经理自己要写代码吗?
    管理系统书籍《从程序员到项目经理》 从程序员到项目经理(一)
    宗宁:赚快钱的那些坑。。(转载)
    java 实现二分法
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6183508.html
Copyright © 2011-2022 走看看