【LibreOJ】#538. 「LibreOJ NOIP Round #1」数列递推

【题意】LibreOJ

【算法】乱搞

【题解】容易发现数列最后一定单调,最后单调递增则最大值赋为最后一个,反之最小值赋为最后一个,然后处理一些细节就可以AC,要注意以下几点:

1.数列连续三项以及数列最后一项>10^7时退出。

2.可能第一要求项就比你枚举的大,需要特判。

3.要求项的枚举不能等于最大项,不然会无法正常指向最后一个。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<map>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>0?x:-x;}
//int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f,maxn=500010;
const ll MAXS=1e15;

int n,m,k,s[maxn];
ll a[maxn];
int main(){
//    freopen("seq8.in","r",stdin);
//    freopen("hi.out","w",stdout);
    int mx=0;
    m=read();
    for(int i=1;i<=m;i++)s[i]=read(),mx=max(s[i],mx);
    n=read();
    int N=min(90,mx);
    for(int i=1;i<=n;i++){
        int now=N;
        a[0]=read();a[1]=read();k=read();
        for(int j=2;j<=N;j++){
            a[j]=1ll*k*a[j-1]+a[j-2];
            if((a[j]>=0&&a[j-1]>=0&&a[j-2]>=0&&a[j]>MAXS)||(a[j]<=0&&a[j-1]<=0&&a[j-2]<=0&&a[j]<-MAXS)){now=j;break;}
        }
        ll mins=1ll<<60,maxs=-(1ll<<60);
        int maxi=-1,mini=-1;
        for(int j=1;j<=m;j++)if(s[j]<now){
            if(a[s[j]]>maxs)maxs=a[s[j]],maxi=s[j];
            if(a[s[j]]<mins)mins=a[s[j]],mini=s[j];
        }else break;
        if(maxi==-1)maxi=s[1];
        if(mini==-1)mini=s[1];
        if(a[now]>0&&a[now]>maxs)maxi=mx;
        if(a[now]<0&&a[now]<mins)mini=mx;
        printf("%d %d
",maxi,mini);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/onioncyc/p/7791466.html