码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3666-Making the Grade(左偏树 or DP)

时间:2016-08-22 00:27:21      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:

左偏树

炒鸡棒的论文左偏树的特点及其应用

虽然题目要求比论文多了一个条件,但是……只需要求非递减就可以AC……数据好弱……

虽然还没想明白为什么,但是应该觉得应该是这样——求非递减用大顶堆,非递增小顶堆……

这题和bzoj1367题意差不多,但是那题求的是严格递增。(bzoj找不到那道题,可能是VIP或什么原因?

严格递增的方法就是每一个数字a[i]都要减去i,这样求得的b[i]也要再加i,保证了严格递增(为什么对我就不知道了

代码比较水,因为题目数据的问题,我的代码也就钻了空子,反正ac就好了。。。。

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

const int N = 2005;
typedef long long ll;

struct LTree {
    int l, r, sz;
    int key, dis;
    bool operator<(const LTree lt) const {
        return key < lt.key;
    }
} tr[N];
int cnt_tr;

int NewTree(int k) {
    tr[++cnt_tr].key = k;
    tr[cnt_tr].l = tr[cnt_tr].r = tr[cnt_tr].dis = 0;
    tr[cnt_tr].sz = 1;
    return cnt_tr;
}

int Merge(int x, int y) {
    if (!x || !y) return x + y;
    if (tr[x] < tr[y]) swap(x, y);
    tr[x].r = Merge(tr[x].r, y);
    if (tr[tr[x].l].dis < tr[tr[x].r].dis) swap(tr[x].l, tr[x].r);
    tr[x].dis = tr[tr[x].r].dis + 1;
    tr[x].sz = tr[tr[x].l].sz + tr[tr[x].r].sz + 1;
    return x;
}

int Top(int x) {
    return tr[x].key;
}

void Pop(int &x) {
    x = Merge(tr[x].l, tr[x].r);
}

int a[N], root[N], num[N];

int main() {
    int n;
    while (~scanf("%d",&n)) {
        ll sum, tmp, ans;
        cnt_tr = sum = tmp = 0;
        for (int i = 0; i < n; ++i) {
            scanf("%d", a+i);
            sum += a[i];
        }
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
            root[++cnt] = NewTree(a[i]);
            num[cnt] = 1;
            while (cnt > 1 && Top(root[cnt]) < Top(root[cnt-1])) {
                cnt--;
                root[cnt] = Merge(root[cnt], root[cnt+1]);
                num[cnt] += num[cnt+1];
                while (tr[root[cnt]].sz*2 > num[cnt]+1) Pop(root[cnt]);
            }
        }
        int px = 0;
        for (int i = 1; i <= cnt; ++i)
            for (int j = 0, x = Top(root[i]); j < num[i]; ++j)
                tmp += abs(a[px++]-x);
        ans = tmp;

        printf("%lld\n", ans);
    }
    return 0;
}

 

这题DP也很神奇,挖坑,明天学……

POJ3666-Making the Grade(左偏树 or DP)

标签:

原文地址:http://www.cnblogs.com/wenruo/p/5793936.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!