【题意】有n个大楼,给你n-1个数a[i]表示位置i之前(包括位置i)有多少栋递增的高楼。问完整序列可能有多少种,也可能无解。
【思路】竟然神游着把a[i]想成高度,推翻了想出来的正解……分三种情况:1、无解:a[i]>max+2或是多个a[i]==max+2;(max∈(a[1]……a[i-1])),无解;2、中间断开:有一个a[i]==max+2;(max∈(a[1]……a[i-1])),用剩下的来补,补在pos之前大于max的空位上;3、有解且不断开:每位有1~max+1个数可插入,重复要删除。
【代码】
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=1000006;
int n,a[maxn],mx,f=1,hst=0,pos=0,hig;
ll ans=1;
inline int get(){
char c;while(!isdigit(c=getchar()));
int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48;
return v;
}
int main(){
n=get();mx=0;
for(int i=1;i<n;++i){
a[i]=get();
if(!f)continue;
if(a[i]>hst+2){f=0;continue;}
if((a[i]==hst+2)&&pos){f=0;continue;}
if(a[i]==hst+2)pos=i,hig=hst;
hst=max(hst,a[i]);
}
if(f && !pos)for(int i=1;i<n;++i){
mx=max(mx,a[i]);
if(1<=a[i] && (a[i]<=mx+1))ans+=(ll)mx;
else ans+=(ll)mx+1;
}
if(f && pos){
ans=0;
for(int i=1;i<=pos;++i){
if(mx==hig)++ans;
mx=max(mx,a[i]);
}
}
if(!f)printf("0\n");
else printf("%lld\n",ans);
return 0;
}