• [ZJOI2010]数字计数


    这道题题意清晰明了。

    最好的方法用前缀差求,即$[0,B]-[0,A-1]$。

    首先拆位把每位存到数组中,并求出位数$L$。

    然后把这些数当成$L$位进行统计,不足$L$位的先补前缀$0$。

    最后减去多余的前缀$0$即可。

    下面求$[0,A]$各个数出现次数的方法大体是:

    例如$[0,1320]$:

    $1320$中$L$为$4$,第一位为$1$,有一位$0$在$1$之前,所以统计$0***$的所有解,而后三位每位一定出现了$1000 imes L / 10$次,第一位$0$出现$1000$次。而$1$只出现了$320$次。

    取出后三位$320$,现在只需统计$[0,320]$中各位出现次数。

    有三位$0$、$1$、$2$出现在$3$之前,所以统计$0**$、$1**$、$2**$的所有解,后两位每位出现了$100 imes L / 10$,第一位$0$、$1$、$2$分别出现了$100$次,而$3$只出现了$20$次。

    取出后两位$20$,便只要统计$[0,20]$中各位出现次数了。

    后面略。

    下面的写法就是将上面的理解抽象。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define re register
     6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
     7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
     8 #define maxx(a, b) a = max(a, b);
     9 #define minn(a, b) a = min(a, b);
    10 #define LL long long
    11 #define inf (1 << 30)
    12 
    13 inline LL read() {
    14     LL w = 0, f = 1; char c = getchar();
    15     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
    16     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
    17     return w * f;
    18 }
    19 
    20 const int maxl = 16;
    21 
    22 LL f1[maxl], f2[maxl], A, B, p[maxl];
    23 int L, bit[maxl];
    24 
    25 void make(LL x) {
    26     L = x ? 0 : 1;
    27     while (x) bit[++L] = x % 10, x /= 10;
    28 }
    29 
    30 void solve(LL *f, LL V) {
    31     rep(i, 1, L-1) f[0] -= p[i]; 
    32     while (L) {
    33         rep(i, 0, bit[L]-1) f[i] += p[L-1];
    34         if (L>1) rep(i, 0, 9) f[i] += bit[L] * p[L-2] * (L-1);
    35         V -= bit[L] * p[L-1];
    36         f[bit[L]] += V+1; L--;
    37     }
    38 }
    39 
    40 int main() {
    41     p[0] = 1;
    42     rep(i, 1, 14) p[i] = p[i-1] * 10;
    43 
    44     A = read(), B = read();
    45     make(A-1); solve(f1, A-1);
    46     make(B); solve(f2, B);
    47     rep(i, 0, 9) printf("%lld ", f2[i] - f1[i]);
    48     return 0;
    49 }
  • 相关阅读:
    Bellman-Ford(BF)和Floyd算法
    Dijkstra实现最短路径
    【图论】连通分量个数(并查集)
    【模拟】n a^o7 !
    【图论】最小生成树
    【搜索DFS】图的深度遍历(dfs)
    【搜索BFS】poj3278--Catch That Cow(bfs)
    【图论】判断给定图是否存在合法拓扑序列
    二叉排序树
    【树】判断给定森林中有多少棵树(简单做法)
  • 原文地址:https://www.cnblogs.com/ac-evil/p/10350995.html
Copyright © 2020-2023  润新知