末日的传说
n位数最多构成n*(n-1)/2个逆序对
首先二分答案求出需要改动的位数k最少是多少
将前面不需要改动的位输出
再算一下构成(k-1)*(k-2)/2个逆序对后还剩多少逆序对
若剩x,就将剩下的数中第x大的数先输出,这样就又构成的x个逆序对
剩下的数倒序输出
#include<iostream> #include<cstring> #include<cstdio> int n; long long m; inline void print(int x){ if(x>9) print(x/10); putchar(x%10+'0'); } int main() { scanf("%d%d",&n,&m); int l=1,r=n; while(l<r){ long long mid=(l+r)>>1; if((mid*(mid-1)>>1)>=m) r=mid; else l=mid+1; } for(register int i=1;i<=n-l;i++) print(i),putchar(' '); int res=m-((long long)l-1)*((long long)l-2)/2; if(res<500000){ print(n-l+1+res); putchar(' '); } for(register int i=n;i>n-l;i--) if(i!=n-l+1+res) print(i),putchar(' '); return 0; }
少用long long可以卡常数