构造好题推荐——逃亡 (mex)
题面
样例输入
5
样例输出
9
22
题解
思路
首先考虑,如果当前数字在第 iii 位,那么其就出现在 i(n−i+1)i(n-i+1)i(n−i+1) 个序列中,容易发现,i+(n−i+1)=n+1i+(n-i+1)=n+1i+(n−i+1)=n+1为定值,故当iii与n−i+1n-i+1n−i+1相差最小时,包含其的序列数量就最多。考虑最小值,那么就是让包含000的序列数尽量少,包含111的序列数尽量少……。即构造序列1,2,4……5,3,01,2,4……5,3,01,2,4……5,3,0,容易求出答案。考虑最大值,那么就是让包含000的序列数尽量多,包含111的序列数尽量多……。即构造序列……4,2,0,1,3…………4,2,0,1,3…………4,2,0,1,3……,容易求出答案。
代码
只要构造出来,求答案方法多样。
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,a[N],t[N],dd[N];
bool bj[N];
int main()
{freopen("mex.in","r",stdin);freopen("mex.out","w",stdout);cin>>n;int ans1=n-1+n;long long ans2=0;
// n++;int l=(n+1)>>1,r=l,cnt=0,num=0;a[l]=0;t[0]=l;while(cnt<n){cnt++;a[++r]=cnt;t[cnt]=r;if(cnt==n) break;cnt++;a[--l]=cnt;t[cnt]=l;}
// for(int i=1;i<=n;i++)
// cout<<a[i]<<" ";
//// cout<<"\n";for(int i=1;i<=(n+1)/2;i++){int d=a[i]-1;if(a[i]==0) d=0;ans2+=1ll*(1+d+2)*((d+2+1)>>1)/2;ans2+=1ll*(n-t[d])*(a[i]+2);}cout<<ans1<<"\n"<<ans2; return 0;}