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. ...
随机推荐
- 洛谷 P2419 [USACO08JAN]牛大赛Cow Contest
题目背景 [Usaco2008 Jan] 题目描述 N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a p ...
- COGS 264. 数列操作
时间限制:1 s 内存限制:160 MB [问题描述] 假设有一列数 {Ai }(1 ≤ i ≤ n) ,支持如下两种操作: (1)将 A k 的值加 D .( k, D 是输入的数) (2) 输 ...
- 集成iAd广告
在iPhone程序中集成广告,管他能不能赚钱,不放上一个iAd就心有不甘. 参考了下面这篇文章: http://bees4honey.com/blog/tutorial/how-to-add-iad- ...
- JavaScript判断数组是否包含指定元素的方法
本文实例讲述了JavaScript判断数组是否包含指定元素的方法.分享给大家供大家参考.具体如下: 这段代码通过prototype定义了数组方法,这样就可以在任意数组调用contains方法 /** ...
- mac文件夹怎么重命名?苹果电脑文件夹重命名快捷键
windows系统下给文件夹重命名相信很多朋友都很熟悉,那么Mac OS系统怎么给文件重命名呢,相信很多刚刚入手Mac OS系统的亲们都会有次疑问,下面小编告诉你Mac OS系统的文件夹到底要怎样才能 ...
- 浏览器window产生的缓存九种解决办法
浏览器缓存(Browser Caching)是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户.浏览器 ...
- 求NEXT数组和KMP匹配的两种写法
注释掉的是我不喜欢的写法. //计算串str的next数组 void getnext(char *str){ int len=strlen(str); ,k=-; next[]=-; while(j& ...
- BZOJ 4016 最短路径树问题 最短路径树构造+点分治
题目: BZOJ4016最短路径树问题 分析: 大家都说这是一道强行拼出来的题,属于是两种算法的模板题. 我们用dijkstra算法算出1为源点的最短路数组,然后遍历一下建出最短路树. 之后就是裸的点 ...
- [CODEVS] 3955 最长严格上升子序列(加强版)
题目描述 Description 给一个数组a1, a2 ... an,找到最长的上升降子序列ab1<ab2< .. <abk,其中b1<b2<..bk. 输出长度即可. ...
- 收集自网络上有关Kali的各种源
更新源总结 #更新源 gedit /etc/apt/sources.list #中科大kali源 deb http://mirrors.ustc.edu.cn/kali kali-rollin ...