【题解】LOJ#538. 「LibreOJ NOIP Round #1」数列递推【数学】

题目链接

题意

给定集合 \(S\)\(n\) 次询问:

  • 给定 \(a_0\in\mathbf{Z},a_1\in\mathbf{N},k\in\mathbf{N^+}\),序列 \(a_{i+2}=ka_{i+1}+a_i,i\in \mathbf{N}\),查询 \(\min\limits_{s\in S}a_s\)

\(n\leq 3\times 10^{5}\)\(k\leq 10^{3}\)\(|S|\leq 10^{5}\)\(s\leq 10^{9}\)\(-10^{7}\leq a_0,a_1\leq 10^7\)

题解

\(a\) 从第 \(O(\log \max(a_0,a_1))\) 次项开始序列就是单调的。所以不单调的部分可以直接枚举,后面就是 \(O(1)\) 计算。

代码:

#include<bits/stdc++.h>
using namespace std;
int getint(){
    int ans=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ans=ans*10+c-'0';
        c=getchar();
    }
    return ans*f;
}
const int N=1e5+10;
int s[N],n;
long double a[N];

int main(){
    n=getint();
    for(int i=0;i<n;i++)s[i]=getint();
    int q=getint();
    while(q --> 0){
        bool boo=0;
        a[0]=getint(),a[1]=getint();
        int k=getint();
        if(a[0]==0&&a[1]==0){ printf("%d %d\n",s[0],s[0]);continue; }
        long double mx=max(a[0],a[1]),mn=min(a[0],a[1]);
        for(int i=2;i<N;i++){
            a[i]=a[i-1]*k+a[i-2];
            if(a[i]>=a[i-1]&&a[i-1]>=0&&a[i]>mx){
                int mx=s[0],mn=s[0];
                for(int j=0;j<n;j++){
                    if(s[j]>=i){
                        if(a[i]||a[i-1])mx=s[n-1];
                        break;
                    }
                    if(a[s[j]]>a[mx])mx=s[j];
                    if(a[s[j]]<a[mn])mn=s[j];
                }
                printf("%d %d\n",mx,mn);
                boo=1;
                break;
            }
            if(a[i]<=a[i-1]&&a[i-1]<=0&&a[i]<mn){
                int mx=s[0],mn=s[0];
                for(int j=0;j<n;j++){
                    if(s[j]>=i){
                        if(a[i]||a[i-1])mn=s[n-1];
                        break;
                    }
                    if(a[s[j]]>a[mx])mx=s[j];
                    if(a[s[j]]<a[mn])mn=s[j];
                }
                printf("%d %d\n",mx,mn);
                boo=1;
                break;
            }
            mx=max(mx,a[i]);
            mn=min(mn,a[i]);
        }
    }
    return 0;
}

posted @ 2020-10-07 17:18  破壁人五号  阅读(195)  评论(0编辑  收藏  举报