zoukankan      html  css  js  c++  java
  • 【LibreOJ NOIP Round #1】数列递推

    这要是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
    ",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
    ",s[1]-1,s[n]-1);
    30             continue;
    31         }
    32         if(a[1]>0 && a[2]>0){
    33             printf("%lld %lld
    ",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
    ",s[n]-1,s[1]-1);
    44             else  printf("%lld %lld
    ",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
    ",mx-1,mn-1);
    55         }
    56     }
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    Java1:Chapter3
    css3圆角和阴影效果
    css3兼容各版本浏览器前缀
    DOM
    数组方法
    Math方法
    JSON
    字符串方法
    日期对象
    定时器
  • 原文地址:https://www.cnblogs.com/cdcq/p/14471578.html
Copyright © 2011-2022 走看看