[CF911E]Stack Sorting
题目大意:
给你两个数组a和b,一个栈s。给你两种操作:
1.从a中取出第一个元素,加入s中;
2.从s的顶端取出一个元素,加入b的末端。
一开始a中有n个元素,s和b是空的。
定义数组b是stack-sortable的,当且仅当a中数通过任意操作后,使b称为一个含有n个元素的不下降数列。
现在告诉你a的前k个元素,问是否存在一种a,使得b为stack-sortable的,如果是,输出字典序最大的一种。
思路:
定义a(b,e)为取值范围从b到e的合法数列,那么a(b,e)=x+a(b,x-1)+a(x+1,e)。
具体操作是先把x加入s,再把a(b,x-1)加入s,然后先后把a(b,x-1)和x加入b,最后把a(x+1,e)加入b,显然这样是合法的。
然后贪心构造,如果当前区间没有限制,就从e到b填数,否则填当前限定的数。如果当前无法填数,则不存在合法解。
1 #include<cstdio> 2 #include<cctype> 3 #include<cstdlib> 4 #include<algorithm> 5 inline int getint() { 6 register char ch; 7 while(!isdigit(ch=getchar())); 8 register int x=ch^'0'; 9 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 10 return x; 11 } 12 const int N=200001; 13 int a[N],b[N]; 14 void solve(const int &b,const int &e,const int &l,const int &r) { 15 if(l>r) { 16 for(register int i=e;i>=b;i--) ::b[++::b[0]]=i; 17 return; 18 } 19 const int &x=::b[++::b[0]]=a[l]; 20 if(x<b||x>e) { 21 puts("-1"); 22 exit(0); 23 } 24 solve(b,x-1,l+1,std::min(l+x-b,r)); 25 solve(x+1,e,l+x-b+1,r); 26 } 27 int main() { 28 const int n=getint(),k=getint(); 29 for(register int i=1;i<=k;i++) { 30 a[i]=getint(); 31 } 32 solve(1,n,1,k); 33 for(register int i=1;i<=n;i++) { 34 printf("%d%c",b[i]," \n"[i==n]); 35 } 36 return 0; 37 }