ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】P2602[JZOI2010]数字计数

2019-02-08 14:37:52  阅读:289  来源: 互联网

标签:10 int 题解 JZOI2010 233 P2602 ccf dp define


【题解】[P2602ZJOI2010]数字计数

乍看此题,感觉直接从数字的位上面动手,感觉应该很容易。

但是仔细看数据范围,发现如果不利用计数原理,肯定会超时,考虑数码出现的特征:

\(A000\)到\(A999\),四位数中的\(A\)总共出现了\(999-0+1\)次。假设\(A\)在第\(k\)位上,那么它出现了\(10^{k-1}\)次。记录一下这个的前缀和。特别注意的是, 由\(dp(i)\rightarrow dp(i+1)\)时,要\(dp(i+1)=10dp(i)+10^{i-1}\),这是考虑到在第\(i+1\)位上增加一位会给\(i\)位带来\([0,9]\)总共10的贡献。那么\(A\)出现的次数就被我们确定了。

显然对于\(A233\)这样的数字,我们不能直接调用前面我们预处理的数组,因为它的值域是在\([233,995]\)的,而非\([000,999]\)。其实这样也好办,\(A\)出现的次数直接就是\(233-000+1=233+1\)。最后对于\(A\)特殊处理即可。

然后我们从处理四位数到了处理三位数了。就是一个一样的子问题。

#include<bits/stdc++.h>

using namespace std;
#define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
#define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
#define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
#define Max(a,b) ((a)<(b)?(b):(a))
#define Min(a,b) ((a)<(b)?(a):(b))
#define midd register int mid=(l+r)>>1
#define TMP template < class ccf >
typedef long long ll;
#define endl '\n'
#define spc ' '
#define int ll
TMP inline ccf qr(ccf b){
    char c=getchar();
    int q=1;
    ccf x=0;
    while(c<48||c>57)
    q=c==45?-1:q,c=getchar();
    while(c>=48&&c<=57)
    x=x*10+c-48,c=getchar();
    return q==-1?-x:x;
}
const int maxn=15;
ll F,T;
int cntf,cntt;
int ans[maxn];
int ans2[maxn];
int num[maxn];
ll dp[maxn]={0,1};
ll ten[maxn]={1};

inline void dfs(int* d,ll data){
    register int cnt=0;
    while(data)
    num[++cnt]=data%10,data/=10;
    
    DRP(t,cnt,1){
    RP(i,0,9)
        d[i]+=dp[t-1]*num[t];
    RP(i,0,num[t]-1)
        d[i]+=ten[t-1];
    register ll temp=0;
    DRP(i,t-1,1)
        temp=temp*10LL+num[i];
    d[num[t]]+=temp+1;d[0]-=ten[t-1];
    }
}


signed main(){
#ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    freopen("out.out","w",stdout);
#endif
    
    ten[1]=10;
    RP(t,2,14)
    ten[t]=ten[t-1]*10ll,dp[t]=dp[t-1]*10ll+ten[t-1];
    
    F=qr(1ll);
    T=qr(1ll);
    
    dfs(ans,T);
    dfs(ans2,F-1LL);

    RP(t,0,9)
    cout<<ans[t]-ans2[t]<<spc;
    cout<<endl;
    return 0;
}

标签:10,int,题解,JZOI2010,233,P2602,ccf,dp,define
来源: https://www.cnblogs.com/winlere/p/10356171.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有