zoukankan      html  css  js  c++  java
  • 【题解】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;
    }
    
    
    知识共享许可协议
    若文章内无特别说明,公开文章采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
  • 相关阅读:
    CSS hack
    字符串中常用的方法
    排序算法
    拾遗
    数组类型检测
    数组常用的方法
    go 文件服务器(标准库) 添加关机,睡眠,退出功能
    go cmd 交互 初始化执行某些命令
    go 内网IP及外网IP获取
    go 快排实现
  • 原文地址:https://www.cnblogs.com/wallbreaker5th/p/13778084.html
Copyright © 2011-2022 走看看