JZOJ3462【休息(rest)】

休息(rest)

题目描述:
休息的时候,可以放松放松浑身的肌肉,打扫打扫卫生,感觉很舒服。在某一天,某LMZ 开始整理他那书架。已知他的书有n 本,从左到右按顺序排列。他想把书从矮到高排好序,而每一本书都有一个独一无二的高度Hi。他排序的方法是:每一次将所有的书划分为尽量少的连续部分,使得每一部分的书的高度都是单调下降,然后将其中所有不少于2 本书的区间全部翻转。重复执行以上操作,最后使得书的高度全部单调上升。可是毕竟是休息时间,LMZ 不想花太多时间在给书排序这种事上面。因此他划分并翻转完第一次书之后,他想计算,他一共执行了多少次翻转操作才能把所有的书排好序。LMZ 惊奇地发现,第一次排序之前,他第一次划分出来的所有区间的长度都是偶数。

输入:
第一行一个正整数n, 为书的总数。

接下来一行n个数,第i个正整数Hi,为第i 本书的高度。

输出:
仅一个整数,为LMZ 需要做的翻转操作的次数。

这道题可以先手动翻一轮。
然后我们可以发现只有两两翻转区间的端点有可能有问题(没排好)。
于是显然我们会考虑两两交换。
但是有可能会牵扯出其他的不合法的东西。
然后又不可能让你一个一个翻。所以还不如直接求逆序对。

然后考场想联系一下线段树。然后就写了线段树的做法。

l o n g l o n g long long 时候来计算后发现要开所以就直接全部开了。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;

const ll N = 100010;

inline void read(ll &x)
{
    char ch = getchar(); x = 0;
    for(;ch < '0' || ch > '9';) ch = getchar();
    for(;ch >= '0' && ch <= '9';) x = x * 10 + (ch ^ '0'), ch = getchar();
}

ll t[N << 2];
ll n,a[N],b[N],ans = 0,cnt = 0;

#define ls p << 1
#define rs ls | 1

void insert(ll p,ll x,ll tl,ll tr)
{
    if(tl > tr) return;
    if(tl == tr) { t[p] = 1; return; }
    ll mid = tl + tr >> 1;
    x <= mid ? insert(ls,x,tl,mid) : insert(rs,x,mid + 1,tr);
    t[p] = t[ls] + t[rs]; 
}

ll query(ll p,ll l,ll r,ll tl,ll tr)
{
    if(tl > tr) return 0;
    if(l <= tl && tr <= r) return t[p];
    ll mid = tl + tr >> 1,ret = 0;
    if(mid >= l) ret += query(ls,l,r,tl,mid);
    if(mid < r) ret += query(rs,l,r,mid + 1,tr);
    return ret;
}

int main()
{
    read(n); cnt = 0; a[0] = N;
    for(int i = 1;i <= n; ++ i) read(a[i]);

    for(int l = 1,r = 1;r <= n && l <= n;cnt = 0)
    {
        while((a[r] < a[r - 1] || l == r) && r <= n) b[++cnt] = a[r], ++r;
        sort(b + 1,b + 1 + cnt);
        for(int i = 1;i <= cnt; ++ i) a[i + l - 1] = b[i];
        l = r; ++ans;
    }

    for(int i = n;i >= 1; -- i)
        a[i] > 1 && (ans += query(1,1,a[i] - 1,1,n)), insert(1,a[i],1,n);
    
    printf("%lld",ans);
    return 0;
}

当然还有树状数组和归并排序的做法。这里便不再赘述。

猜你喜欢

转载自blog.csdn.net/INnovate2030/article/details/102816355
今日推荐