题目描述

农夫栋栋近年收入不景气,正在他发愁如何能多赚点钱时,他听到隔壁的小 朋友在讨论兔子繁殖的问题。 问题是这样的:第一个月初有一对刚出生的小兔子,经过两个月长大后,这 对兔子从第三个月开始,每个月初生一对小兔子。新出生的小兔子生长两个月后 又能每个月生出一对小兔子。问第 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. redis删除所有key

    flushdb 删除当前数据库的所有keyflushall  删除所有数据库的所有keydbsize   返回当前数据库的key的数量

  2. 读JVM相关的一些笔记

    1.JVM的运行模式 vm一般有两种运行模式,client和server(JDK 7 后有第三种 Tiered server,后续会涉及到). client : 启动快,内存占用少,JIT编译器生成代 ...

  3. redis主从,哨兵回忆手册

    redis主从 持久化的开启与主从集群是否生效无关系 Slave Server同样是以非阻塞的方式完成数据同步.在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据(注意初次同步则会阻 ...

  4. Fast Paxos

    http://blog.csdn.net/chen77716/article/details/7297122 自从Lamport在1998年发表Paxos算法后,对Paxos的各种改进工作就从未停止, ...

  5. Jenkins实现Android自动化打包

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/77102359 本文出自[赵彦军的博客] 1.Tomcat 进入 https://t ...

  6. CentOS7安装codeblocks(转载)

    1.安装gcc,需要c和c++两部分,默认安装下,CentOS不安装编译器的,在终端输入以下命令即可 yum install gccyum install gcc-c++ 2.安装gtk2-devel ...

  7. java数组遍历、java方法定义

    1.遍历数组for与foreach String [] test =  {"java","php","bootstrap","vu ...

  8. [Java算法分析与设计]--线性结构与顺序表(List)的实现应用

    说到线性结构,我们应该立马能够在脑子里蹦出"Array数组"这个词.在Java当中,数组和对象区别基本数据类型存放在堆当中.它是一连串同类型数据存放的一个整体.通常我们定义的方式为 ...

  9. PAT1046: Shortest Distance

    1046. Shortest Distance (20) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The ...

  10. 我热爱Coding,但厌恶这个IT互联网

    在我十岁的时候,我觉得这个世界上没有什么东西能比我老爸的那台破电脑更好玩的了.后来,我成为一名Web开发爱好者.大学毕业之后,我在一个软件公司工作,那个时候赚得并不多.再后来,我成为一名正式的Web开 ...