Count Numbers

时间限制: 8 Sec  内存限制: 128 MB

题目描述

Now Alice wants to sum up all integers whose digit sum is exactly ab .
However we all know the number of this kind of integers are unlimited. So she decides to sum up all these numbers whose each digit is non-zero.
Since the answer could be large, she only needs the remainder when the answer divided by a given integer p.

输入

The input has several test cases and the first line contains the integer t (1 ≤ t ≤ 400) which is the number of test cases.
For each test case, a line consisting of three integers a, b (1 ≤ a, b ≤ 20) and p (2 ≤ p ≤ 109 ) describes the restriction of the digit sum and the given integer p.

输出

For each test case, output a line with the required answer.
Here we provide an explanation of the following sample output. All integers satisfying the restriction in the input are 4, 13, 31, 22, 121, 112, 211 and 1111. The sum of them all is 4 + 13 + 31 + 22 + 121 + 112 + 211 + 1111 = 1625 and that is exactly the sample output.

样例输入

5
2 1 1000000
3 1 1000000
2 2 1000000
3 3 1000000
10 1 1000000

样例输出

13
147
1625
877377
935943

题意:求十进制下各个位上的数字和为n的数的总和。
分析:首先n很大,要用__int128来存,其次要能求出关于n的递推式。分析n=k的情况,我们尝试来构造出这些满足条件的数。如果这个数的最后一位为1,那么就需要求出所有k-1的答案数字,然后在其最后加上1,如果最后一位为2,那么就需要求出所有k-2的答案数字,然后在其最后加上2,。。。。。。。
一直可以分析到最后一位为9的情况。那么我们需要两个数组ans[i],cut[i],ans[i]代表n=i时的答案是多少,cut[i]代表n=i时满足数字和是i的数字有多少个。因此就可以推出递推公式:cut[i]=sum(cut[i-j]){1<=j<=9},ans[i]=sum(10*ans[i-j]+j*cut[i-j]){1<=j<=9}。
有了递推式就可以套矩阵快速幂了,这里要注意矩阵要开18*18的,这样方便转移状态。
还有要注意的就是矩阵最好写成int类型的,以防超时。(顺便mark一下加取模和乘取模的函数)。
最后一点就是矩阵乘法可以放弃以往的一行乘一列的写法,用一种新的写法,这样可以省下不少时间。
#include<bits/stdc++.h>
//#define __int128 long long
using namespace std;
long long p=1e9+; int addmod(int a,int b) //加法取模
{
return a+b>=p?a+b-p:a+b;
}
int mulmod(long long a,int b) //乘法取模
{
return a*b%p;
} struct Mat
{
int v[][]; Mat()
{
memset(v, , sizeof(v));
}
void init()
{
for (int i=; i<; i++)
v[i][i]=(int);
} };
Mat operator *(Mat a,Mat b)
{
Mat c;
for (int i=; i<; i++)
{
for (int j=; j<; j++) //换了一种写法,节省计算0的时间
if(a.v[i][j])
{
for (int k=; k<; k++)
if(b.v[j][k])c.v[i][k]=addmod(c.v[i][k],mulmod(a.v[i][j]%p,b.v[j][k]%p));
}
}
return c;
} Mat qmod(Mat a,__int128 k)
{
Mat c;
c.init(); while (k>)
{
if (k&) c=c*a;
a=a*a;
k>>=;
}
return c;
} int main()
{
long long ans[]= {},cut[]= {};
cut[]=;
for(int i=; i<=; i++)
for(int j=; j<=i; j++)ans[i]+=*ans[i-j]+j*cut[i-j],cut[i]+=cut[i-j]; Mat a,b; for(int i=; i<; i++)a.v[][i]=;
for(int i=; i<; i++)a.v[][i]=i-;
for(int i=; i<; i++)a.v[i][i-]=;
for(int i=; i<; i++)a.v[][i]=;
for(int i=; i<; i++)a.v[i][i-]=; int t;
scanf("%d",&t);
while(t--)
{
long long aa,bb;
scanf("%lld %lld %lld",&aa,&bb,&p); for(int i=; i<; i++)b.v[i][]=ans[-i]%p;
for(int i=; i<; i++)b.v[i][]=cut[-i]%p; __int128 now=aa;
for(int i=; i<=bb; i++)now=now*(__int128)aa; if(now<=)
{
printf("%lld\n",ans[now]%p);
continue;
} Mat c=qmod(a,now-)*b;
printf("%lld\n",c.v[][]); }
return ;
}

Count Numbers的更多相关文章

  1. Count Numbers(矩阵快速幂)

    Count Numbers 时间限制: 8 Sec  内存限制: 128 MB提交: 43  解决: 19[提交] [状态] [讨论版] [命题人:admin] 题目描述 Now Alice want ...

  2. LC 357. Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  3. [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  4. Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  5. Leetcode: Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  6. 357. Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  7. 【Leetcode】357. Count Numbers with Unique Digits

    题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. ...

  8. [Swift]LeetCode357. 计算各个位数不同的数字个数 | Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...

  9. Java [Leetcode 357]Count Numbers with Unique Digits

    题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. ...

随机推荐

  1. 【GIMP学习】抠图方法二则

    之前抠图都比较二,懒人我尝试过在线抠图软件.以及在线PS简易版,真的都很不好用,前者简单粗暴,后者我遇到各种储存不能的bug. 在ubuntu的环境下有一个功能可以和PS相媲美的功能强大图片处理软件G ...

  2. build.sbt的定义格式

    一个简单的build.sbt文件内容如下: name := "hello" // 项目名称 organization := "xxx.xxx.xxx" // 组 ...

  3. (六)使用Docker镜像(下)

    1. 创建镜像 创建镜像的方法有三种: 基于已有镜像的容器创建 基于本地模板导入 基于Dockerfile创建 1.1 基于已有镜像的容器创建 该方法主要是使用docker commit命令,其格式 ...

  4. beta版本发布-团队

    一.β版本于α版本的不同 1.α版本先前只可电脑单机使用,β版本已成功解决联网问题,可以在不同电脑上正常使用 2.β版本相较于α版本修补了较多漏洞.进行了界面的优化且新增了学生个人信息维护功能.教师的 ...

  5. WINDOWS-API:取得系统语言种类-GetOEMCP

    GetOEMCP VB声明 Declare Function GetOEMCP Lib "kernel32" Alias "GetOEMCP" () As Lo ...

  6. fckeditor的实例

                            第一步:去官网下载,删除多余的包 删除所有”_”开头的文件和文件夹   删除FCKeditor的目录下:   fckeditor.afp fckedit ...

  7. 监控linux各主机系统时间是否一致

    #!/bin/bashSTATE_OK=0 STATE_WARNING=1 STATE_CRITICAL=2 STATE_UNKNOWN=3PASSWD='**************'print_h ...

  8. java在线聊天项目 实现基本聊天功能后补充的其他功能详细需求分析 及所需要掌握的Java知识基础 SWT的激活方法,swt开发包下载,及破解激活码

    补充聊天项目功能,做如下需求分析: 梳理项目开发所需的必要Java知识基础 GUI将使用更快速的swt实现 SWT(Standard Widget Toolkit) Standard Widget T ...

  9. TCP头校验和计算算法详解

    我就不管是按“位”(bit)取反相加,还是 按“1的补码”相加了,总之就是把需要进行校验的“字串”加(+)起来,把这相加的 结果取反当做“校验和” (Checksum), 比如,相加的结果是0101, ...

  10. python基础知识14-正则表达式

    1.正则表达式 正则可以代替其他任何工具,但是其他工具不能完全代替正则. 1.匹配或提取字符串的工具,基于所有语言之上的工具. 正则表达式所面向的问题 判断一个字符串是否匹配给定的格式,如判断用户注册 ...