• Codeforces


    题目链接
    题目大意:给你一个数字(n),问你在(000...000)(999...999)((10^{n-1})位)里面长度为(1,2...n)里的块有多少(相等的连续子段算一块)。
      我们可以尝试构造出长度为i的块,对于一个长度为i的块来说:
      1.若它在数字的边缘,那么它右边(或左边)的第一个数一定与块内的数不同,又因为这个块可以在左边缘也可以在右边缘,所以这(i+1)个数一共有(10 imes 9 imes 2)种情况,而剩下的部分有(n-i-1)位,所以就有(10^{n-i-1})种情况。所以一共是(10 imes 9 imes 2 imes 10^{n-i-1})种情况。
      2.若他不在数字的边缘,那么它的左右两边都有不同的数字,所以这(i+2)这个数就有(10 imes 9 imes 9)种情况,而剩下的部分有(n-i-2)位,所以就有(10^{n-i-2})种情况。但是还没完,这个块还可以平移,每次平移一位,我们的情况数就会增加,因为我们的一个块带上两边一共有(i+2)的长度,所以一共可以平移(n-(i+2))次,再算上本身的这一次,一共是(10 imes 9 imes 9 imes 10^{n-i-2} imes (n-(i+2)+1))种情况。
      关于会不会算多或者算少的问题,我们每次算的只是所有数中长度为(i)的一部分,这些部分累加起来才是一个完整的数,所以不存在一个完整的数被多次计算的情况,也不会有一个完整的数没有被完全计算的情况。

    const int maxn = 2e5+10;
    ll ans[maxn];
    ll qpow(ll x, int y) {
        ll res = x%MOD, ans = 1;
        while(y) {
            if (y&1) ans = ans*res%MOD;
            res = res*res%MOD;
            y >>= 1;
        }
        return ans%MOD;
    }
    int main(void) {
        ll n;
        scanf("%lld", &n);
        ans[n] = 10, ans[n-1] = 180;
        for (ll i = 1; i<=n-2; ++i)
            ans[i] = (ans[i] + 10LL*9*2*qpow(10, n-i-1)%MOD + 10LL*9*9*(n-i-1)%MOD*qpow(10, n-i-2))%MOD;
        for (int i = 1; i<=n; ++i)
            printf(i==n ? "%lld
    " : "%lld ", ans[i]);
        return 0;
    }
    
  • 相关阅读:
    使用AD你应该避免的五个错误
    卸载常用组件
    学会批处理,用心学很容易
    VI的用法
    安装Linux版VNC 企业版
    【3】淘宝sdk的下载和安装
    【7】创建一个自己的模板
    【6】网店模板目录及文件介绍
    【11】淘宝sdk的DOM、CSS规范、Widget规范(这个Widget规范差不多就是网页效果)和HTML规范
    【2】认识淘宝sdk模板
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12567270.html
Copyright © 2020-2023  润新知