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. python numpy 判断ndarray 中是否有 nan

    numpy.isnan(myarray).any() 下面讨论了哪一种方法的速度最快 reference: stackoverflow.com/questions/911871/detect-if-a ...

  2. Linq to xml 读取xml文件或xml字符串

    XMLFile1.xml: XDocument Contacts = XDocument.Load("XMLFile1.xml"); //XElement Contacts = X ...

  3. web综合案例04

    web综合案例02 web综合案例02 web综合案例04 待补充 ... ...

  4. Linux调优(内存,CPU)

    一.相关概念简介 system call:系统调用 time slice:cpu时间片 O(1):Linux系统进程调度器 page frame:分页 RSS:常驻内存集,无法被页面化的数据 MMU: ...

  5. Linux 下的dd命令使用详解

    转自:https://www.cnblogs.com/jikexianfeng/p/6103500.html 一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意 ...

  6. H5页面开发的touchmove事件

    在做一屏滚动的H5页面的时候,必须移除touchmove事件,如果不移除,在安卓机上会触发微信原生的向下滚动拉出刷新.在IOS上出现上下都可以继续滑动,所以需要移除document的touchmove ...

  7. BZOJ 1053 [HAOI2007]反素数ant 神奇的约数

    本蒟蒻终于开始接触数学了...之前写的都忘了...忽然想起来某神犇在几个月前就切了FWT了... 给出三个结论: 1.1-N中的反素数是1-N中约数最多但是最小的数 2.1-N中的所有数的质因子种类不 ...

  8. Vue 2 --v-model、局部组件和全局组件、父子组件传值、平行组件传值

    一.表单输入绑定(v-model 指令) 可以用 v-model 指令在表单 <input>.<textarea> 及 <select> 元素上创建双向数据绑定. ...

  9. java多线程关键字volatile的使用

    java多线程关键字volatile的作用是表示多个线程对这个变量共享. 如果是只读的就可以直接用,写数据的时候要注意同步问题. 例子: package com.ming.thread.volatil ...

  10. smarty模板引擎之if, elseif else

    Smarty 中的 if 语句和 php 中的 if 语句一样灵活易用,并增加了几个特性以适宜模板引擎. if 必须于 /if 成对出现. 可以使用 else 和 elseif 子句. 可以使用以下条 ...