模拟9:T1:斐波那契
Description:
题目描述:
小 C 养了一些很可爱的兔子。
有一天,小 C 突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子。我们假定,在整个过程中兔子不会出现任何意外。
小 C 把兔子按出生顺序,把兔子们从 1 开始标号,并且小 C 的兔子都是 1 号兔子和 1号兔子的后代。如果某两对兔子是同时出生的,那么小 C 会将父母标号更小的一对优先标号。
如果我们把这种关系用图画下来,前六个月大概就是这样的:
其中,一个箭头 A→B 表示 A 是 B 的祖先,相同的颜色表示同一个月出生的兔子。
为了更细致地了解兔子们是如何繁衍的,小 C 找来了一些兔子,并且向你提出了 个问题:她想知道关于每两对兔子 和 ,他们的最近公共祖先是谁。你能帮帮小 C 吗? 一对兔子的祖先是这对兔子以及他们父母(如果有的话)的祖先,而最近公共祖先是指两对兔子所共有的祖先中,离他们的距离之和最近的一对兔子。比如,5 和 7 的最近公共祖先是 2,1 和 2 的最近公共祖先是 1,6 和 6 的最近公共祖先是 6。
输入格式
输入第一行,包含一个正整数。
输入接下来m行,每行包含 2 个正整数,表示 和。
输出格式
输出一共行,每行一个正整数,依次表示你对问题的答案。
样例
样例输入
5
1 1
2 3
5 7
7 13
4 12
样例输出
1
1
2
2
4
数据范围:
这个题题目暗示的太明显了,斐波那契数。
先说一下70分解法:
我们观察图中的树,可以发现,每一代的子代个数满足斐波那契数(从第二代开始)
其实可以推的:
每一代增加的兔子数是上数第二代的兔子数,因为每一只兔子一个月只生一只,且从出生第二个月开始生育,那么就有这一代新增兔子的表达式:
f[i]=f[i-1]+f[i-2]
i表示第几代子代,i从3开始(第一、二代不用公式手模也知道啊(逃));
并且,编号小的兔子的子代编号也小,那么就这一代的兔子从小往大里父亲是1、2……
然后就可以建树了。
建树后就可以直接跑LCA了。70分到手。
这是作者本人考场上的想法。
70分代码:
#include<bits/stdc++.h>
using namespace std;
namespace Decleration
{
#define ll long long
#define rr register
#define pp pair<int,int>
const int SIZEM=300014,SIZEAB=1e6+4;
int m,maxn=INT_MIN;
int a[SIZEM],b[SIZEM];
int to[SIZEAB<<1],last[SIZEAB];
int dire[SIZEAB<<1];
queue<int> q;
inline int max(rr int x,rr int y){return x>y?x:y;}
inline void add(int f,int t)
{
static int num=0;
*(to+(++num))=t;
*(dire+num)=*(last+f);
*(last+f)=num;
}
void build(int x)
{
int now=1,en;
q.push(1);
while(1)
{
int fi=1,se=1,l=1;
while(1)
{
int cnt=0;
int t=se+fi;
for(rr int i=l+1;i<=t;i++)
add(++cnt,i),add(i,cnt);
fi=se;
se=t;
l=t;
if(t>=x) return;
}
}
}
int read()
{
rr int x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=getchar();
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
};
using namespace Decleration;
namespace L_C_A
{
int fa[SIZEAB],son[SIZEAB];
int size[SIZEAB],top[SIZEAB];
int depth[SIZEAB];
void dfs1(int x)
{
size[x]=1;
for(rr int i=last[x];i;i=dire[i])
{
if(to[i]==fa[x]) continue;
fa[to[i]]=x;
depth[to[i]]=depth[x]+1;
dfs1(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]]) son[x]=to[i];
}
}
void dfs2(int x)
{
if(x==son[fa[x]]) top[x]=top[fa[x]];
else top[x]=x;
for(rr int i=last[x];i;i=dire[i])
{
if(to[i]==fa[x]) continue;
dfs2(to[i]);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(depth[top[x]]>depth[top[y]]) x=fa[top[x]];
else y=fa[top[y]];
}
if(depth[x]<depth[y]) return x;
return y;
}
};
using namespace L_C_A;
int main()
{
m=read();
for(rr int i=1;i<=m;i++)
{
a[i]=read(),b[i]=read();
maxn=max(maxn,a[i]),maxn=max(maxn,b[i]);
}
build(maxn);
dfs1(1);
dfs2(1);
for(rr int i=1;i<=m;i++)
printf("%d\n",LCA(a[i],b[i]));
}
这里我用的树链剖分求的LCA,比ST快。
这个代码仅供参考,我考场上只得了50分RE了,估计是哪里没写好,大家以此为思路参考就好了。
接下来说正解。
我们既然已经想出来那个式子了,按理说正解就顺理成章了(然而我考试没多想,那70分就走人了),我们可以发现,还是根据那个式子,每一个点减去比他小的斐波那契数中最大的那一个得到的就是他的父亲,那么我们就可以利用这个性质,一点一点往上跳父亲找LCA,100分到手。
#include<bits/stdc++.h>
using namespace std;
namespace Decleration
{
#define ll long long
#define rr register
const int SIZEM=300014;
ll m;
ll f[64];
ll read()
{
rr ll x_read=0,y_read=1;
rr char c_read=getchar();
while(c_read<'0'||c_read>'9')
{
if(c_read=='-') y_read=getchar();
c_read=getchar();
}
while(c_read<='9'&&c_read>='0')
{
x_read=(x_read<<3)+(x_read<<1)+(c_read^48);
c_read=getchar();
}
return x_read*y_read;
}
int bound(rr ll x)
{
int l=1,r=60;
while(l<r)
{
rr int mid=(l+r+1)>>1;
if(f[mid]<=x) l=mid;
else r=mid-1;
}
if(f[l]==x) l--;
return l;
}
ll LCA(rr ll a,rr ll b)
{
int i1=bound(a),i2=bound(b);
while(a!=b)
{
if(i1>i2) a-=f[i1],i1=bound(a);
//i大意味着深度大,优先跳深度大的,为什么,我不解释,留给您自己思考
else b-=f[i2],i2=bound(b);
}
return a;
}
};
using namespace Decleration;
int main()
{
m=read();
f[1]=f[2]=1;
for(rr int i=3;i<=62;i++)
f[i]=f[i-1]+f[i-2];
//第60个斐波那契数就已经大于a,b的上限了,当然,也爆long long了
for(rr int i=1;i<=m;i++)
{
ll a=read(),b=read();
printf("%lld\n",LCA(a,b));
}
}
2021.6.22 现役
模拟9:T1:斐波那契的更多相关文章
- 【洛谷mNOIP模拟赛Day1】T1 斐波那契
题目传送门:https://www.luogu.org/problemnew/show/P3938 这题出得特别吼啊~~ 通过打表或者大胆猜想斐波那契数列的一些性质,我们不难发现对于一只兔子$x$,其 ...
- NOIP模拟赛T3 斐波那契
1.题目 求 \[\sum_{i=1}^n \sum_{j=1}^m \gcd(F_i,F_j) \] 其中 \(F_k\) 表示斐波那契数列的第 \(k\) 项,对 \(10^9 + 7\) 取模. ...
- 20190803 NOIP模拟测试12「斐波那契(fibonacci)· 数颜色 · 分组 」
164分 rank11/64 这次考的不算太差,但是并没有多大的可能性反超(只比一小部分人高十几分而已),时间分配还是不均,T2两个半小时,T1半个小时,T3-额十几分钟吧 然额付出总是与回报成反比的 ...
- noip模拟9[斐波那契·数颜色·分组](洛谷模拟测试)
这次考试还是挺好的 毕竟第一题被我给A了,也怪这题太简单,规律一眼就看出来了,但是除了第一题,剩下的我只有30pts,还是菜 第二题不知道为啥我就直接干到树套树了,线段树套上一个权值线段树,然后我发现 ...
- [NOIP1997] P2626 斐波那契数列(升级版)
题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数). 题目描述 ...
- 2019.8.3 NOIP模拟测试12 反思总结【P3938 斐波那契,P3939 数颜色,P3940 分组】
[题解在下面] 早上5:50,Gekoo同学来到机房并表态:“打暴力,打暴力就对了,打出来我就赢了.” 我:深以为然. (这是个伏笔) 据说hzoi的人还差两次考试[现在是一次了]就要重新分配机房,不 ...
- Python基础(二):斐波那契数列、模拟cp操作、生成8位随机密码
一.斐波那契数列 目标: 编写fib.py脚本,主要要求如下: 输出具有10个数字的斐波那契数列 使用for循环和range函数完成 改进程序,要求用户输入一个数字,可以生成用户需要长度的斐波那契数列 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- NOIP模拟题 斐波那契数列
题目大意 给定长度为$n$序列$A$,将它划分成尽可能少的若干部分,使得任意部分内两两之和均不为斐波那契数列中的某一项. 题解 不难发现$2\times 10^9$之内的斐波那契数不超过$50$个 先 ...
随机推荐
- 计算距离2020年圣诞节还有x天x时x分x秒
//计算两者相差毫秒数 //创建当前时间和圣诞节时间的Date对象 var d1=new Date(); var d2=new Date('2020/12/25'); //计算相差的毫秒 var d= ...
- NOIP&CSP PJ 难度刷题记录
前言 本来不想写前言的(>人<:) 这只是 mjl 给我们布置的作业,并不是我自己在刷题! 不保证所有代码的正确性,它们仅仅是通过了所有数据点而已. 1.模拟板块 整体难度:红~黄(模拟不 ...
- 812考试总结(NOIP模拟37)[数列·数对·最小距离·真相]
前言 考得挺憋屈的... 先是搞了两个半小时的 T1 后来发现假了,又没多想跳了.. 然后一看 T2 这不是队长快跑嘛... 先是根据自己的想法打了一遍(考完之后发现是对的..) 然后回想了一下之前的 ...
- MySQL Utilities工具教程
一.MySQL Utilities介绍 MySQL Utilities 提供一组命令行工具用于维护和管理 MySQL 服务器,包括: 管理工具 (克隆.复制.比较.差异.导出.导入)复制工具 (安装. ...
- Spring源码阅读-BeanFactory体系结构分析
BeanFactory是Spring中非常重要的一个类,搞懂了它,你就知道了bean的初始化和摧毁过程,对于深入理解IOC有很大的帮助. BeanFactory体系结构 首先看一下使用IDEA生成的继 ...
- Build VM Cluster on CentOS Host
Host Machine [root@bocoty49 ~]# lsb_release -a LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0 ...
- 题解 Star Way To Heaven
传送门 这整场都不会--这题想二分不会check 其实check很好写,考虑一个mid的实际意义 即为check在不靠近每个star及边界mid距离内的前提下,能不能到达\((n,m)\) 其实可以转 ...
- docker 实现redis主从复制
目录 一.概览 二.安装master库 三.安装slave从库 四.错误分析 五.参考网址 一.概览 主库:192.168.3.13:6380 从库一:192.168.3.14:6381 从库二:19 ...
- shell 函数返回值与字典
shell的函数只能返回整数值,如果想让函数返回字符串可以在函数调用处为变量赋值. # 定义函数function test() { name=$1 echo "123213" } ...
- 一:Tomcat安装、配置和部署笔记
Tomcat安装(绿色版安装) 1.将下载的Tomcat解压到指定目录,如:D:\WorkSpaceByJava\DevtTools\Apache-Tomcat-8.0.23 2.Tomcat的目录结 ...