G Link with Monotonic Subsequence
对于[1-n]的一种排列,求其最长上升子序列和最长下降子序列的最大值的最小值
排列权值的最小值为sqrt(n)
#include<bits/stdc++.h>
using namespace std;
template <typename tn>void read(tn &n){
tn f=1,t=0;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) t=t*10+ch-'0',ch=getchar();
n=f*t;
}
inline void out(int x){
if(x>9)out(x/10);
putchar(x%10+'0');
}
int T,n,num,sum;
int calc(int n){
for(int i=2;i<=n;++i){
int x=n/i;
if(n%i!=0)x++;
if(x<i)return i-1;
}
return 0;
}
int main(){
read(T);
while(T--){
read(n);
if(n==1){cout<<"1"<<endl;continue;}
if(n==2){cout<<"1 2"<<endl;continue;}
num=calc(n);
sum=n/num;
if(n%num==0){
for(int i=num-1;i>0;--i)
for(int j=1;j<=sum;++j)
cout<<sum*i+j<<" ";
for(int i=1;i<=sum-1;++i)cout<<i<<" ";
cout<<sum<<endl;
}
if(n%num!=0){
sum++;
for(int i=n-(n%sum)+1;i<=n;++i)cout<<i<<" ";
num--;
for(int i=num-1;i>0;--i)
for(int j=1;j<=sum;++j)
cout<<sum*i+j<<" ";
for(int i=1;i<=sum-1;++i)cout<<i<<" ";
cout<<sum<<endl;
}
}
return 0;
}