题意
给定集合 \(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;
}