Count Numbers
Count Numbers
时间限制: 8 Sec 内存限制: 128 MB
题目描述
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.
输入
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.
输出
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的更多相关文章
- Count Numbers(矩阵快速幂)
Count Numbers 时间限制: 8 Sec 内存限制: 128 MB提交: 43 解决: 19[提交] [状态] [讨论版] [命题人:admin] 题目描述 Now Alice want ...
- 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 ...
- [LeetCode] Count Numbers with Unique Digits 计算各位不相同的数字个数
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- Count Numbers with Unique Digits
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- Leetcode: Count Numbers with Unique Digits
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- 357. Count Numbers with Unique Digits
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Examp ...
- 【Leetcode】357. Count Numbers with Unique Digits
题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. ...
- [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 ...
- 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. ...
随机推荐
- java 使用htmlunit模拟登录爬取新浪微博页面
mport java.io.IOException;import java.net.MalformedURLException;import com.gargoylesoftware.htmlunit ...
- Prim算法解决最小生成树
一.最小生成树问题 什么是最小生成树问题?给你一个带权连通图,需要你删去一些边,使它成为一颗权值最小的树. 二.Prim算法 1)输入:输入一个带权连通图,顶点集合V,边集合E 2)初始化:Vnew= ...
- 用valgrind检查内存问题
Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...
- STL:string类中size()与length()的区别
结论是:两者没有任何区别 解释: C++Reference中对于两者的解释: 两者的具体解释都一模一样: 理解: length是因为C语言的习惯而保留下来的,string类最初只有length,引进S ...
- 单源最短路Dijstra
#include<iostream> #include<cstring> #define INF 0x3f3f3f3f using namespace std; ][],d[] ...
- ajax的traditional属性
jquery框架的ajax参数除了常用的 $.ajax({ url: 'xxx', type: 'xxx', data: 'xxx', success: 'xxx' ... }) 外还有一个参数需要特 ...
- shell脚本,通过传入的参数来计算最大值和最小值以及平均值。
[root@localhost zuoye]# cat quansges.sh #!/bin/bash > file [ ! $# -ge ] && || echo $* > ...
- PLAYGROUND 延时运行
PLAYGROUND 延时运行 由 王巍 (@ONEVCAT) 发布于 2015/09/16 从 WWDC 14 的 Keynote 上 Chris 的演示就能看出 Playground 异常强大,但 ...
- noip_最后一遍_3-数据结构
noip基础数据结构太多了又太捞了 所以也就那么几个了 单调队列滑动窗口 #include<bits/stdc++.h> using namespace std; #define maxn ...
- 解决 mounting /dev/block/mmcblk0p1 on /sdcard failed
http://www.liyu8.com/article/sdcard.htm 之前在recovery下的adb shell执行mount -a总是会有 mount: mouting /dev/blo ...