Count Numbers

时间限制: 8 Sec  内存限制: 128 MB
提交: 43  解决: 19
[提交] [状态] [讨论版] [命题人:admin]

题目描述

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来存。如果这个数的最后一位为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的,这样方便转移状态。
最后一点就是矩阵乘法可以放弃以往的一行乘一列的写法,用一种新的写法,这样可以省下不少时间。
构造的矩阵(n大于9时,用于以n==9为基础往上递推,n小于等于9时直接暴力)为:

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p;
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]=;
}
} };
Mat operator *(Mat a,Mat b)
{
Mat c;
for (int i=; i<; i++)
{
for (int j=; j<; j++)
{
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()
{
ll ans[]={},cut[]={};
ll aa,bb,t;
__int128 now;
Mat a,b,c;
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];
}
}
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-]=;
scanf("%lld",&t);
while(t--)
{
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;
now=aa;
for(int i=; i<=bb; i++) now=now*(__int128)aa;
if(now<=)
{
printf("%lld\n",ans[now]%p);
continue;
}
c=qmod(a,now-)*b;
printf("%lld\n",c.v[][]);
}
return ;
}

注意:__int128在有的情况下不能编译!!!

												

Count Numbers(矩阵快速幂)的更多相关文章

  1. hdu 3117 Fibonacci Numbers 矩阵快速幂+公式

    斐波那契数列后四位可以用快速幂取模(模10000)算出.前四位要用公式推 HDU 3117 Fibonacci Numbers(矩阵快速幂+公式) f(n)=(((1+√5)/2)^n+((1-√5) ...

  2. HDU 6470 Count 【矩阵快速幂】(广东工业大学第十四届程序设计竞赛 )

    题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6470 Count Time Limit: 6000/3000 MS (Java/Others)    ...

  3. Project Euler 435 Polynomials of Fibonacci numbers (矩阵快速幂)

    题目链接: https://projecteuler.net/problem=435 题意: The Fibonacci numbers $ {f_n, n ≥ 0}$ are defined rec ...

  4. HDU 6470:Count(矩阵快速幂)

    Count Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  5. Sam's Numbers 矩阵快速幂优化dp

    https://www.hackerrank.com/contests/hourrank-21/challenges/sams-numbers 设dp[s][i]表示产生的总和是s的时候,结尾符是i的 ...

  6. 省选模拟赛 Problem 3. count (矩阵快速幂优化DP)

    Discription DarrellDarrellDarrell 在思考一道计算题. 给你一个尺寸为 1×N1 × N1×N 的长条,你可以在上面切很多刀,要求竖直地切并且且完后每块的长度都是整数. ...

  7. 广工十四届校赛 count 矩阵快速幂

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6470 题意:求,直接矩阵快速幂得f(n)即可 构造矩阵如下: n^3是肯定得变换的,用二项式展开来一点 ...

  8. HDU 3117 Fibonacci Numbers( 矩阵快速幂 + 数学推导 )

    链接:传送门 题意:给一个 n ,输出 Fibonacci 数列第 n 项,如果第 n 项的位数 >= 8 位则按照 前4位 + ... + 后4位的格式输出 思路: n < 40时位数不 ...

  9. UOJ424 Count 生成函数、多项式求逆、矩阵快速幂

    传送门 两个序列相同当且仅当它们的笛卡尔树相同,于是变成笛卡尔树计数. 然后注意到每一个点的权值一定会比其左儿子的权值大,所以笛卡尔树上还不能够存在一条从根到某个节点的路径满足向左走的次数\(> ...

随机推荐

  1. go语言实战教程:实战项目资源导入和项目框架搭建

    从本节内容开始,我们将利用我们所学习的Iris框架的相关知识,进行实战项目开发. 实战项目框架搭建 我们的实战项目是使用Iris框架开发一个关于本地服务平台的后台管理平台.平台中可以管理用户.商品.商 ...

  2. smix到底是个啥?Perl的正则表达式匹配模式

    最近在研究一个perl项目,临时学习了一下perl语法,强行看项目源码.因为总是见到各种正则表达式后面接smxi之类,虽然知道是匹配模式,但脑子里毫无概念.所以特地去学习了一下. 以上为背景. Per ...

  3. informix 入门简单笔记

    informix 查看数据库 服务名字 onstat -c | grep DBSERVER 例如: DBSERVERNAME easycon # Name of default database se ...

  4. CentOS 6.6 x64安装TensorFlow

    CentOS 6.6 x64安装TensorFlow升级Python到2.7(系统自带Python版本为2.6) // 安装编译工具 $ yum -y install gcc automake aut ...

  5. codeforces round 472(DIV2)D Riverside Curio题解(思维题)

    题目传送门:http://codeforces.com/contest/957/problem/D 题意大致是这样的:有一个水池,每天都有一个水位(一个整数).每天都会在这一天的水位上划线(如果这个水 ...

  6. springBoot实现socketio

    https://github.com/mrniko/netty-socketio-demo https://github.com/mrniko/netty-socketio

  7. Options Menu的android3.0以上和以下版本显示刷新原理,刷新适配

    一 显示区别: 2.3.x及以下版本,需要按菜单键显示菜单,当菜单打开时,第一个可见的部分是图标菜单,最多可容纳6个菜单项.如果你的菜单包括Android的地方超过6项,第六项,其余将被归到”More ...

  8. UnityVR Steam_VR开发工具插件---VRTK 自带案例分析

  9. SpringBoot | 第二章:lombok介绍及简单使用

    在去北京培训的时候,讲师说到了lombok这个第三方插件包,使用了之后发现,确实是个神奇,避免了编写很多臃肿的且定式的代码,虽然现代的IDE都能通过快捷键或者右键的方式,使用Generate Gett ...

  10. RPC框架设计思路

    RPC是指远程过程调用 1.要解决通讯的问题,主要是通过在客户端和服务器之间建立TCP连接,远程过程调用的所有交换的数据都在这个连接里传输.连接可以是按需连接,调用结束后就断掉,也可以是长连接,多个远 ...