loj 数列递推
老师说要每天都要写总结(老师一直叫我写,我怎么写啊,对面酒桶一直进我野区.....不对,对面题目一直不会做
要求给定数列s[n],a[s[i]]的最大值和最小值,i={1,2,.....,n}(别笑了,不知道∑怎么写)
因为 a[i]=k*a[i-1]+a[2]
所以a数组的函数图像最后一段绝对会呈现递增或递减的样子
所以最大和最小的答案里有定有一个是s[n]
因为会有一段是凹凸不平的,但是特别短,所以暴力在这一段找最小值或最大值就行了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e5+5;
const ll INF=1e14;
int n,m,s[N];
ll a[105];
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
m=read();
for(int i=1;i<=m;i++)
s[i]=read();
int n=read();
for(int i=1;i<=n;i++)
{
memset(a,0,sizeof(a));
a[0]=read(),a[1]=read();
int k=read(),mi=s[1],mx=s[1];
if(!a[0]&&!a[1])
printf("%d %d\n",s[1],s[1]);
else
{
int p=1;
for(p=2;p<=100&&abs(a[p]=(k*a[p-1]+a[p-2]))<=INF;p++);
p--;
for(int i=1;i<=m&&s[i]<=p;i++)
{
if(a[s[i]]==a[mi])
mi=min(mi,s[i]);
if(a[s[i]]==a[mx])
mx=min(mx,s[i]);
if(a[s[i]]<a[mi])
mi=s[i];
if(a[s[i]]>a[mx])
mx=s[i];
}
if(s[m]>100)
a[p]<0?mi=s[m]:mx=s[m];
printf("%d %d\n",mx,mi);
}
}
return 0;
}
(sd代码