题目描述

农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小 朋友在讨论兔子繁殖的问题。 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这 对兔子从第三个月开始,每个月初生一对小兔子。新出生的小兔子生长两个月后 又能每个月生出一对小兔子。问第 n 个月有多少只兔子? 聪明的你可能已经发现,第 n 个月的兔子数正好是第 n 个 Fibonacci(斐波那 契)数。栋栋不懂什么是 Fibonacci 数,但他也发现了规律:第 i+2 个月的兔子数 等于第 i 个月的兔子数加上第 i+1 个月的兔子数。前几个月的兔子数依次为: 1 1 2 3 5 8 13 21 34 … 栋栋发现越到后面兔子数增长的越快,期待养兔子一定能赚大钱,于是栋栋 在第一个月初买了一对小兔子开始饲养。 每天,栋栋都要给兔子们喂食,兔子们吃食时非常特别,总是每 k 对兔子围 成一圈,最后剩下的不足 k 对的围成一圈,由于兔子特别害怕孤独,从第三个月 开始,如果吃食时围成某一个圈的只有一对兔子,这对兔子就会很快死掉。 我们假设死去的总是刚出生的兔子,那么每个月的兔子数仍然是可以计算的。 例如,当 k=7 时,前几个月的兔子数依次为: 1 1 2 3 5 7 12 19 31 49 80 … 给定 n,你能帮助栋栋计算第 n 个月他有多少对兔子么?由于答案可能非常 大,你只需要告诉栋栋第 n 个月的兔子对数除 p 的余数即可。

输入

输入一行,包含三个正整数 n, k, p。

输出

输出一行,包含一个整数,表示栋栋第 n 个月的兔子对数除 p 的余数。

样例输入

6 7 100

样例输出

7

题解:

  矩阵快速幂+......万恶的分类讨论。

  %%%%http://blog.csdn.net/u011265346/article/details/46331419

  

#include<cstdio>
#include<map>
#include<iostream>
#include<cstring>
using namespace std;
map<long long ,int >mp;
typedef long long ll;
const int N=(int ) 1e6+;
inline ll powmod(ll a,ll b,ll p){
ll ans=;
while(b){
if(b&) ans=a*ans%p;
a=a*a%p;
b>>=;
}return ans;
}
int vis[*N];
ll n,k,p,phi_k;
ll fib[*N];
ll step[N];
int cnt,from;
bool circle;
inline ll gcd(ll a,ll b){
return b==?a:gcd(b,a%b);
}
inline ll phi(ll x){
ll ans=;
for(ll i=;i*i<=x;i++)
if(x%i==){
ans*=i-;
x/=i;
while(x%i==)
x/=i,ans*=i;
}
return ans*(x==?:x-);
}
inline void init(){
phi_k=phi(k);
fib[]=fib[]=;
for(int i=;i<=*k;i++){
fib[i]=(fib[i-]+fib[i-])%k;
if(!vis[fib[i]])
vis[fib[i]]=i;
}
for(ll i=,j;;){
mp[i]=++cnt;
ll t=gcd(i,k);
if(t>) break;
else{
j=powmod(i,phi_k-,k);
if(!vis[j]){
break;
}
else{
i=i*fib[vis[j]-]%k;
step[cnt]=(ll)vis[j];
if(mp.count(i)){
circle=true;
from=mp[i];break;
}
}
}
}
step[]-=;
}
struct Matrix{
ll a[][];
Matrix(){memset(a,,sizeof(a));}
void e(){
a[][]=a[][]=a[][]=a[][]=;
}
void f(){
a[][]=a[][]=a[][]=;a[][]=-;
}
friend Matrix operator *(Matrix x,Matrix y){
Matrix c;
for(int i=;i<=;i++)
for(int j=;j<=;j++){
for(int k=;k<=;k++)
(c.a[i][j]+=x.a[i][k]*y.a[k][j])%=p;
(c.a[i][j]+=p)%=p;
}
return c;
}
friend Matrix operator ^(Matrix x,ll b){
Matrix ans;
for(int i=;i<=;i++) ans.a[i][i]=;
while(b){
if(b&) ans=ans*x;
b>>=;
x=x*x;
}return ans;
}
void print(){
for(int i=;i<=;i++){
for(int j=;j<=;j++)printf("%lld ",a[i][j]);puts("");
}
}
}a,b;
ll ans;
inline void solve(){
if(circle){
n-=;
a.e(),b.f();
Matrix now;
now.a[][]=now.a[][]=now.a[][]=;
int i;
for(i=;i<from&&n>=step[i];n-=step[i],i++)
now=now*(a^step[i])*b;
if(i<from) {
now=now*(a^n);
ans=now.a[][];
return ;
}
else{
ll all_cic=;
for(i=from;i<=cnt;i++)
all_cic+=step[i];
ll cic=n/all_cic;
n-=cic*all_cic;
Matrix c;
for(i=;i<=;i++) c.a[i][i]=;
for(i=from;i<=cnt;i++)
c=c*(a^step[i])*b;
now=now*(c^cic);
for(i=from;n>=step[i];n-=step[i],i++)
now=now*(a^step[i])*b;
now=now*(a^n);
ans=now.a[][];return;
}
}
else{ n-=;
a.e(),b.f();
Matrix now;
now.a[][]=now.a[][]=now.a[][]=;
int i;
for(i=;step[i]&&n>=step[i];n-=step[i],i++){
now=now*(a^step[i])*b;
}
now=now*(a^n);ans=now.a[][];return ;
}
}
int main(){
scanf("%lld%lld%lld",&n,&k,&p);
if(n==){
printf("%lld\n",%p);
return ;
}
init();
solve();
printf("%lld\n",ans);
}

【bzoj2432】【NOI2011】兔农的更多相关文章

  1. [BZOJ2432][Noi2011]兔农 矩阵乘法+exgcd

    2432: [Noi2011]兔农 Time Limit: 10 Sec  Memory Limit: 256 MB Description 农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到 ...

  2. BZOJ2432 [Noi2011]兔农

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  3. 2432: [Noi2011]兔农 - BZOJ

    Description 农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小朋友在讨论兔子繁殖的问题. 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这对兔子从第三个月 ...

  4. NOI2011 兔农

    http://www.lydsy.com/JudgeOnline/problem.php?id=2432 感觉是day1中最难的一题,还好出题人很良心,给了75分部分分. 还是跪拜策爷吧~Orz ht ...

  5. 【BZOJ 2432】 [Noi2011]兔农 矩乘+数论

    这道题的暴力分还是很良心嘛~~~~~ 直接刚的话我发现本蒟蒻只会暴力,矩乘根本写不出来,然后让我们找一下规律,我们发现如果我们把这个序列在mod k的意义下摆出,并且在此过程中把值为1的的数减一,我们 ...

  6. 【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)

    [BZOJ2432][NOI2011]兔农(数论,矩阵快速幂) 题面 BZOJ 题解 这题\(75\)分就是送的,我什么都不想写. 先手玩一下,发现每次每次出现\(mod\ K=1\)的数之后 把它减 ...

  7. 【BZOJ 2437】 2437: [Noi2011]兔兔与蛋蛋 (博弈+二分图匹配**)

    未经博主同意不得转载 2437: [Noi2011]兔兔与蛋蛋 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 693  Solved: 442 Des ...

  8. bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势

    noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...

  9. 【NOI2011】兔农(循环节)

    我居然没看题解瞎搞出来了? 题解: 不难想到找到每次减1的位置,然后减去它对最终答案的贡献. 假设有一个地方是\(x,1(mod~k)\) 那么减了1后就变成了\(x,0\). 然后可以推到\(x,0 ...

随机推荐

  1. 转log4cxx: Could not read configuration file [log4cxx.properties]解决办法

    早上遇到了log4cxx: Could not read configuration file [log4cxx.properties].这个问题.网上搜索后发现是少了log4cxx.properti ...

  2. IE的变态

    1.它自身的内容动态调试功能太简陋. 2.另存成静态网页调试,发现网页代码和原先后台写的根本不一样,能稍微守点规矩行不?

  3. 微博评论箱的隐藏Bug解决

    最近给站点添加社交评论功能,即用微博.QQ帐号就可以在网站上评论.其中Sina微博评论箱在IE和Firefox有个Bug,就是如果初始页面中微博评论箱所在那一部分处于不可见状态,那么后面即使切换了显示 ...

  4. 畅通工程-HZNU寒假集训

    畅通工程 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只 ...

  5. 用js来实现那些数据结构16(图02-图的遍历)

    上一篇文章我们简单介绍了一下什么是图,以及用JS来实现一个可以添加顶点和边的图.按照惯例,任何数据结构都不可或缺的一个point就是遍历.也就是获取到数据结构中的所有元素.那么图当然也不例外.这篇文章 ...

  6. Combination Sum Two

    Description: Given a collection of candidate numbers (C) and a target number (T), find all unique co ...

  7. oracle 游标简单示例

    1.游标的概念以及作用 游标(Cursor)可以使用户想操作数组一样对查询出来的结果集进行操作,可以形象的看做一个变动的光标,其实际行是一个指针,它在一段Oracle存放数据查询结果集或数据 操作集的 ...

  8. 并发编程(十):AQS

    AQS全称为AbstractQueuedSynchronizer,是并发容器中的同步器,AQS是J.U.C的核心,它是抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类都 ...

  9. Github发现优秀的开源项目

    先上个大logo,哈哈. github上有非常多的资源,我们可以在github上搜索到非常多的开源项目.那么如何使用github查找资源? 罗列出一下几种方式. 1.Explore 登录GitHub, ...

  10. HTML DOM对象的属性和方法

    HTML DOM对象的属性和方法 HTML DOM 对象有几种类型: 1.Document 类型 在浏览器中,Document 对象表示整个 HTML 文档. 1.1属性 引用文档的子节点 docum ...