【洛谷P1338】末日的传说

末日的传说

题目描述

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可以卡常数

猜你喜欢

转载自www.cnblogs.com/yjkhhh/p/9361866.html