题目描述

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

    之前就了解到了装饰器, 但是就会点皮毛, 而且对其调用方式感到迷茫,正好现在的项目我想优化,就想到了用装饰器, 因此深入研究了下装饰器.先看下代码: import time # 将函数作为参数传入到此 ...

  2. 小试cordova

    Cordova就是以前的PhoneGap捐献给Apache的最新开源版本. 安装一定要走npm网络方式,需要装Node.js,npm(windows nodejs安装包包含npm),Git.因为必须要 ...

  3. 分布式单点登录框架XXL-SSO

    <分布式单点登录框架XXL-SSO> 一.简介 1.1 概述 XXL-SSO 是一个分布式单点登录框架.只需要登录一次就可以访问所有相互信任的应用系统. 拥有"轻量级.分布式.跨 ...

  4. Linux中mongodb定时远程备份

    下载mongodb https://www.cnblogs.com/tartis/p/5291580.html mongodb定时备份文档 虚拟机报错要改BIOS 虚拟技术开启 进入root账户  s ...

  5. 在高分屏正确显示CHM文件

    今天下了白色相簿2推,发现里面的chm格式的帮助文档显示不正确,又没法在应用程序直接设置系统分辨率托管,google了一下找到了这个方法: 新建 HKEY_LOCAL_MACHINE\ SOFTWAR ...

  6. Java 核心卷学习笔记(一)

    Java基程序设计结构 1.注释 三种注释方式: // 注释单行 /* 内容 */ 注释单行 /** * 内容 */

  7. 1、原生javascript方法小汇

    Js 对象 使用new 关键字来创建对象,举例如下, var a = new String();如构造函数无参数,则不必加括号, JS内部对象数组(Array)对象创建数组var myarray = ...

  8. 【转】mysql索引使用技巧及注意事项

    一.索引的作用 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

  9. Unix系统的常用信号

    编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号).不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信 ...

  10. capwap学习笔记——初识capwap(二)(转)

    2.5.1 AC发现机制 WTP使用AC发现机制来得知哪些AC是可用的,决定最佳的AC来建立CAPWAP连接. WTP的发现过程是可选的.如果在WTP上静态配置了AC,那么WTP并不需要完成AC的发现 ...