ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LibreOJ NOIP Round #1】数列递推

2021-03-02 22:02:21  阅读:236  来源: 互联网

标签:oo ch NOIP LibreOJ ll rd && Round lld


这要是ACM题又是一道自闭题。。。。。。

原题:

 

 

把an表示为p*a0+q*a1的形式,手玩前几项发现不难证明a1系数永远大于a0且越来越大

所以只要这俩别全0,整个数列的走向一定是这样的:

波动->出现相邻同号->起飞

原因很显然,由于a1系数越来越大,所以当n趋向于无穷时a1的符号比a0占优势

而且系数是k的多项式,所以应该飞得很快

担心飞得不够快的可以暴力算各种边界情况,你会发现都会起飞

接下来的难点是将这个规律转化为AC程序,有两个难点

第一个难点是你不知道飞到什么程度才能够保证比前面的都大,我的做法是暴力算前3k个(被卡了,改成300个AC)

第二个难点是爆longlong

我的做法是在暴力的途中,如果发现a[i]>oo(一个很大的数),那么就让a[i]=oo(负数同理)

这样就可以先常规方法找最值点,然后特判一下,如果s[n]已起飞到平流层进入巡航模式,那么就改写最大或最小值点

此外还有很多细节,都标在代码里了,WA了2发才AC,如果是ACM题又要当自闭人力

 

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 using ll=long long int;
 5 //ll oo=(ll)1000000007*1000000007;
 6 ll oo=(ll)1000000007*200000;  //warning: k=5e3
 7 ll rd(){
 8     ll bwl=0,mk=1;
 9     char ch=getchar();
10     while((ch<'0' || ch>'9') && ch!='-')  ch=getchar();
11     if(ch=='-'){  mk=-1;  ch=getchar();}
12     while(ch>='0' && ch<='9'){  bwl=bwl*10+ch-'0';  ch=getchar();}
13     return bwl*mk;
14 }
15 int n,m;
16 ll s[310000],a[310000],k;
17 int main(){
18     n=rd();
19     for(int i=1;i<=n;++i)  s[i]=rd()+1;
20     m=rd();
21     while(m --> 0){
22         a[1]=rd(),a[2]=rd(),k=rd();
23         if(a[1]==0 && a[2]==0){  //warning
24             printf("%lld %lld\n",s[1]-1,s[1]-1);
25             continue;
26         }
27         /*  warning: a[1]<0 a[2]<0 a[1]<a[2]
28         if(a[1]<0 && a[2]<0){
29             printf("%lld %lld\n",s[1]-1,s[n]-1);
30             continue;
31         }
32         if(a[1]>0 && a[2]>0){
33             printf("%lld %lld\n",s[n]-1,s[1]-1);
34             continue;
35         }
36         */
37         for(int i=3;i<=300;++i){
38             a[i]=a[i-1]*k+a[i-2];
39             if(a[i]>oo)  a[i]=oo;
40             if(a[i]<-oo)  a[i]=-oo;
41         }
42         if(s[1]>300 || a[s[1]]==oo || a[s[1]]==-oo){  //warning
43             if(a[300]>0)  printf("%lld %lld\n",s[n]-1,s[1]-1);
44             else  printf("%lld %lld\n",s[1]-1,s[n]-1);
45         }
46         else{
47             ll mx=s[1],mn=s[1];
48             for(int i=1;i<=n && s[i]<=300;++i){
49                 if(a[s[i]]>a[mx])  mx=s[i];
50                 if(a[s[i]]<a[mn])  mn=s[i];
51             }
52             if(a[mx]==oo)  mx=s[n];
53             if(a[mn]==-oo)  mn=s[n];
54             printf("%lld %lld\n",mx-1,mn-1);
55         }
56     }
57     return 0;
58 }
View Code

 

标签:oo,ch,NOIP,LibreOJ,ll,rd,&&,Round,lld
来源: https://www.cnblogs.com/cdcq/p/14471578.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有