CF 633D斐波那契
Posted pedestrian6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 633D斐波那契相关的知识,希望对你有一定的参考价值。
狂WA巨坑题
题意:给出n<=1000个数,能组成的类似斐波那契的数列最长长度是多少(fn=fn-1+fn-2,n>=2)
solution:看起来是一道相当高端的数论题,还是D题?我现在都没现场切过D 没想到做法就是暴力?不过暴力可证复杂度OK
感觉枚举一下前两项,一直往下找,这样用个map维护一下复杂度也是n^3logn啊
不过打个斐波那契数列的表就能发现,因为每个值范围[-1e9,1e9],所以即使数列第一个和第二个是绝对值很小的两个1也会在45项左右停止,这样的话就算50项,复杂度好像可以,不过坑点巨多
坑点1:要把0特殊拿出来,因为如果前两项是0整个数列就全都是0,绝对值不上升,毒瘤数据稳稳卡成n^3logn
坑点2:如果有0要放进去1个,因为可能会有 0,x,x,……或x,0,x……这种操作
坑点3:元素有重啊!答案数列也可能有重,所以map不能存bool要存int
坑点4:map映射元素的个数,所以在原始数组中枚举前两项要去重。如果不去重,极端情况下所有数45个一组正好一个斐波那契数列,然后重复20遍,这样n^2*45,但是不要忘了还有map logn大约是10可能会被卡(99点果然被卡)
坑点5:去完重后,注意数列前两个可以相同,前提是该数出现次数>1
有些神奇刚才unique之前没sort(不能完全去重)竟然过了。。。
1 #include<iostream>
2 #include<cstdio>
3 #include<map>
4 #include<algorithm>
5 using namespace std;
6 map <int,int> M,T;//int开始写成bool了
7 int n,A[2020],ans;
8 int main(){
9 scanf("%d",&n);
10 int i,j;
11 for (i=1;i<=n;i++){
12 scanf("%d",&A[i]);
13 if (!A[i]) i--,n--,ans++;
14 else M[A[i]]++;
15 }
16 if (ans) n++,M[0]=1;//有0的话给去掉0的数列加个0
17 sort(A+1,A+n+1);//忘了
18 n=unique(A+1,A+n+1)-A-1;//去重提高效率
19 for (i=1;i<=n;i++)
20 for (i=1;i<=n;i++) for (j=1;j<=n;j++)
21 if (i==j&&M[A[i]]<2) continue;
22 //不能直接i=j就退出因为数列前两个可能一样
23 else{
24 int cur,a1=A[i],a2=A[j],sum=2;
25 T.clear();
26 T[a1]++; T[a2]++;
27 while (1){
28 cur=a1+a2;
29 if (T[cur]==M[cur]) break;
30 T[cur]++; a1=a2; a2=cur; sum++;
31 }
32 ans=max(ans,sum);
33 }
34 cout<<ans;
35 }
以上是关于CF 633D斐波那契的主要内容,如果未能解决你的问题,请参考以下文章
CF446CDZY Loves Fibonacci Numbers (线段树 + 斐波那契数列)
CF717A Festival Organization(第一类斯特林数,斐波那契数列)