【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\n",maxi,mini); } return 0; }