codevs4247奇特的生物 解析报告
4247 奇特的生物
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题解
题目描述 Description
科学家们最近发现了一种奇怪的生物,它们每天长大一岁,刚出生的宝宝为1岁,且它们的年龄没有上限。已知年龄为1岁,2岁,3岁,……,k岁的个体具有生育能力,当年龄为i的具有生育能力的个体将长大一岁时会生下ai个1岁的幼崽。假设第一天只有一个年龄为1的幼崽,现在科学家们想知道第x天年龄为y的个体有多少,但由于该物种增长速度太快,于是他们将这个任务交给了你。由于这个数可能很大,你需要对p取模。
输入描述 Input Description
输入数据第一行给定四个整数k,x,y,p。
第二行包括k个整数,第i个整数代表ai。
输出描述 Output Description
输出数据包含一行,表示第x天年龄为y的个体的数量对p取模后的结果。
样例输入 Sample Input
【样例输入 1】
3 3 1 1007
1 1 1
【样例输入 2】
3 6 2 1007
1 2 1
样例输出 Sample Output
【样例输出1】
2
【样例输出 2】
13
增加一个新样例。codevs上的第十个点。
莫名其妙的矩阵快速幂解决不了。
样例输入3:
10 10258496531232 52 700000000017
5 89 63 25 48 76 95 23 15 25
样例输出3:
611559827774
分析:
这道题轻轻一想发现。哦。可以用递推来模拟。递推公式大致应该是这个样子的。
由题意可知。每个年龄的数量都是由上个年龄的人长成这个年龄的。而只有1岁的人是靠1-k有生育能力的人生产出来的。
由于这个范围很大。所以很容易让人想到用矩阵乘法来对这个进行递推优化。
但是仔细一想。发现这道题有个性质。就是没个人数都是由上一个转化过来的,那么。其实当F[1]产生的时候。以后的数量就是确定的。所以我们就没必要把全部的情况都存下来。就存1-k,每次进行状态转移就好。其次我们会发现。在整个序列里。因为只有F[1]在变所以我们求 x天y岁人数的问题就转换成了。我们求 x-y+1天1岁的人数问题。为什么呢?。我们y岁人数起时在底x-y+1天就转化好了。而之后剩下的天数,就是将x-y+1天1岁的人转移转移到x天y岁。
接下来的问题就剩到了,如何建立矩阵之后用矩阵来快速幂一些奇怪的事情。
这个矩阵很显然易见的解决这个问题。因为矩阵乘法是第一个举证的行乘第二个的列。所以我们在这里矩阵A第一行就是将F[1~k]里的所有结果相加。之后的行就完成了一个转移的工作。将上一天转换到当前天数。
于是就是将整个矩阵乘上 x-y 次。求A[1][1]--代表第x-y+1天的一岁的人数。
还有既然都是乘x-y次那么我们就要对(y>x)的情况进行特判。还有就是要加上快速乘法。不然第10个点过不去。这个数据就专门来卡你。
贴上代码。
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
long long int mod,k,x,y;
struct node{
long long l[100][100];
node()
{
memset(l,0,sizeof(l));
}
}a,ans;
long long mul(long long x, long long y) {
long long ret = 0;
for(; y; y >>= 1) {
if((y & 1) && (ret += x) >= mod) ret -= mod;
if((x <<= 1) >= mod) x -= mod;
}
return ret;
}
node operator*(node a,node b)
{
node res;
for(int i=1;i<=k;++i)
for(int j=1;j<=k;++j)
{
for(int q=1;q<=k;++q)
{
res.l[i][j] += mul(a.l[i][q], b.l[q][j]);
if(res.l[i][j] >= mod) res.l[i][j] -= mod;
}
}
return res;
}
int main()
{
scanf("%lld%lld%lld%lld",&k,&x,&y,&mod);
for(long long int i=1;i<=k;++i)
{
scanf("%lld",&a.l[1][i]);
a.l[i+1][i]=1;
ans.l[i][i]=1;
}
if(x<y){
printf("0");
return 0;
}
for(long long int i=x-y;i!=0;i>>=1 ,a=a*a)
{
if(i&1)ans=a*ans;
}
printf("%lld",ans.l[1][1]);
return 0;
}
codevs4247奇特的生物 解析报告的更多相关文章
- [codevs4247]奇特的生物
题目描述 Description 科学家们最近发现了一种奇怪的生物,它们每天长大一岁,刚出生的宝宝为1岁,且它们的年龄没有上限.已知年龄为1岁,2岁,3岁,……,k岁的个体具有生育能力,当年龄为i的具 ...
- OpenJudge 2990:符号三角形 解析报告
2990:符号三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“ ...
- BZOJ1088扫雷Mine 解析报告
1088: [SCOI2005]扫雷Mine Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了,“余”人国流行起了一种简单的扫 ...
- OpenJudge 2985数字组合 解析报告/DP
2985:数字组合 总时间限制: 1000ms 内存限制: 65536kB 描述 有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式.如:n=5,5个数分别为1,2,3,4,5,t=5: ...
- openjudge7834:分成互质组 解析报告
7834:分成互质组 总时间限制: 1000ms 内存限制: 65536kB 描述 给定n个正整数,将它们分组,使得每组中任意两个数互质.至少要分成多少个组? 输入 第一行是一个正整数n.1 &l ...
- BZOJ3732 解析报告//LCA,最小生成树
3732: Network 题目描述 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的 ...
- 收集 数据库的awr数据,生成报告
该脚本只是把awr报告的内容,原封不动的 展现出来,做记录 awrreport.sql 脚本内容如下: *********************************************** ...
- 征信接口调用,解析(xml)
数据传输格式报文格式:xml public CisReportRoot queryCisReport(PyQueryBean pyQueryBean) throws Exception { CisRe ...
- 如何使用Postman生成不同格式测试的报告
Postman还可以生成测试报告,还是多种格式报告? Postman团队开源Newman作为Postman运营工具,该开源库使用命令行方式执行Postman 脚本,并且生成多种格式报告,还支持Post ...
随机推荐
- mac电脑如何不生成.DS_STORE文件
执行这个命令,然后重启 defaults write com.apple.desktopservices DSDontWriteNetworkStores true
- mysql 修改root登录密码
mysql -u root -p 然后回车,进入(等于用空密码进入) 2 use mysql; update user set password=password('123456') where us ...
- windows下搭建学习objective-c 的运行环境【转载】
对于Iphone开发学习者而言,Object -c 是必修的语言.但是由于苹果的自我封闭的产业链发展模式(从芯片.机器.开发语言.终端产品.服务)的限制,要想开发针对苹果iPhone等产品的应用程序, ...
- 转:简单的RTSP消息交互过程
简单的RTSP消息交互过程 C表示RTSP客户端,S表示RTSP服务端 1. 第一步:查询服务器端可用方法 1.C->S:OPTION request //询问S有哪些方法可用 ...
- Scala 深入浅出实战经典 第79讲:单例深入讲解及单例背后的链式表达式
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- iOS中的webView加载HTML
在日常开发中,我们为了效率会用到很多很多的WebView,比如在做某个明细页面的时候我们返回给你的可能是一个html字符串,我们就需要将当前字符串展示到webView上面,所以我们对HTML标签需要有 ...
- git的一些相关知识
1.配置多个git远程仓库的ssh-Key切换(转自) 目前的git仓库如github都是通过使用SSH与客户端连接,如果只是固定使用单个git仓库的单个用户 (first),生成生成密钥对后,将公钥 ...
- iOS开发——项目实战总结&Block使用注意点浅析
Block使用注意点浅析 1.在使用block前需要对block指针做判空处理. 不判空直接使用,一旦指针为空直接产生崩溃. if (!self.isOnlyNet) { if (succBlock ...
- Intent用法简介
Intent作为联系各Activity之间的纽带,其作用并不仅仅只限于简单的数据传递.通过其自带的属性,其实可以方便的完成很多较为复杂的操作.例如直接调用拨号功能.直接自动调用合适的程序打开不同类型的 ...
- 单线程vs多线程
a.多线程可以说是实现异步的一种方式: b.共同点:多线程和异步操作两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性: c.线程消费CPU资源. 异步消费硬件资源: 1.多线程和异步操作 ...