zoukankan      html  css  js  c++  java
  • hdu 6012 Lotus and Horticulture 打标记

    http://acm.hdu.edu.cn/showproblem.php?pid=6012

    我们希望能够快速算出,对于每一个温度,都能够算出它在这n颗植物中,能得到多少价值。

    那么,对于第i科植物,在[0, L[i] - 1]这些温度中,得到的价值是低温那个价值,同理在[L[i], R[i]]中,和[R[i], mx]中,

    那么可以用O(1)打标记的思路去完成。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    map<int, LL>book;
    void work() {
        book.clear();
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            int L, R, a, b, c;
            scanf("%d%d%d%d%d", &L, &R, &a, &b, &c);
            book[0] += c;
            book[L << 1] += a - c;
            book[(R << 1) + 1] += b - a;
        }
        LL ans = 0;
        LL tans = 0;
        for (map<int, LL> :: iterator it = book.begin(); it != book.end(); ++it) {
            tans += it->second;
            ans = max(ans, tans);
        }
        printf("%I64d
    ", ans);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code

    同样可以用线段树完成,就是先把坐标离散了,然后区间更新和上面一样的东西。

    线段树维护最大值,seg[cur]表示这课树覆盖的区间,其中某个温度能取得的最大值。

    但是我一直wa,不知为何。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    #define lson L, mid, cur << 1
    #define rson mid + 1, R, cur << 1 | 1
    #define root 1, mx, 1
    const int maxn = 500000 + 20;
    int L[maxn], R[maxn];
    LL a[maxn], b[maxn], c[maxn];
    LL add[maxn << 3], seg[maxn << 3];
    vector<int>da;
    void pushDown(int cur) {
        if (add[cur]) {
            add[cur << 1] += add[cur];
            add[cur << 1 | 1] += add[cur];
            seg[cur << 1 | 1] += add[cur];
            seg[cur << 1] += add[cur];
            add[cur] = 0;
        }
    }
    void pushUp(int cur) {
        seg[cur] = max(seg[cur << 1], seg[cur << 1 | 1]);
        assert(seg[cur] >= 0);
    }
    void build(int L, int R, int cur) {
        seg[cur] = add[cur] = 0;
        if (L == R) {
            return;
        }
        int mid = (L + R) >> 1;
        build(lson);
        build(rson);
        pushUp(cur);
    }
    void upDate(int be, int en, LL val, int L, int R, int cur) {
        if (L >= be && R <= en) {
            seg[cur] += val;
            add[cur] += val;
            return;
        }
        pushDown(cur);
        int mid = (L + R) >> 1;
        if (be <= mid) upDate(be, en, val, lson);
        if (en > mid) upDate(be, en, val, rson);
        pushUp(cur);
    }
    LL query(int be, int en, int L, int R, int cur) {
        if (L >= be && R <= en) return seg[cur];
        pushDown(cur);
        LL ans = 0;
        int mid = (L + R) >> 1;
        if (be <= mid) ans += query(be, en, lson);
        if (en > mid) ans += query(be, en, rson);
        return ans;
    }
    void work() {
        da.clear();
        int n;
        scanf("%d", &n);
        da.push_back(-inf);
        da.push_back(-inf);
        da.push_back(-inf);
        for (int i = 1; i <= n; ++i) {
            scanf("%d%d%I64d%I64d%I64d", &L[i], &R[i], &a[i], &b[i], &c[i]);
            assert(L[i] <= R[i]);
            if (L[i] > R[i]) swap(L[i], R[i]);
            L[i] *= 2;
            R[i] *= 2;
            da.push_back(L[i]);
            da.push_back(R[i]);
        }
        sort(da.begin(), da.end());
        int gg = da.size();
        for (int i = 3; i < gg; ++i) {
            if (da[i] - da[i - 1] == 2) {
                da.push_back(da[i] - 1);
            }
        }
        sort(da.begin(), da.end());
        int mx = 0;
        for (int i = 1; i <= n; ++i) {
            L[i] = lower_bound(da.begin(), da.end(), L[i]) - da.begin();
            R[i] = lower_bound(da.begin(), da.end(), R[i]) - da.begin();
    //        cout << L[i] << " " << R[i] << endl;
            mx = max(mx, R[i] + 2);
        }
    //    cout << endl;
        build(root);
        for (int i = 1; i <= n; ++i) {
            upDate(1, L[i] - 1, c[i], root);
            upDate(L[i], R[i], a[i], root);
            upDate(R[i] + 1, mx, b[i], root);
        }
        cout << query(1, mx, root) << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code

     原来是我离散化错了

    一开始的时候,认为[70, 73]  [74, 76]这样,73和74相邻,那么乘以2后,变成146   148,那么相隔2的时候才添加些元素进去,比如添加147进去隔着,这样离散化。

    这样有bug(还没想到有什么bug)

    现在的思路是:乘以2后,把L[i] + 1和R[i] + 1也放进去,这样就不会有挨着了

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    #define lson L, mid, cur << 1
    #define rson mid + 1, R, cur << 1 | 1
    #define root 1, mx, 1
    const int maxn = 500000 + 20;
    int L[maxn], R[maxn];
    int a[maxn], b[maxn], c[maxn];
    LL add[maxn << 3], seg[maxn << 3];
    vector<int>da;
    void pushDown(int cur) {
        if (add[cur]) {
            add[cur << 1] += add[cur];
            add[cur << 1 | 1] += add[cur];
            seg[cur << 1 | 1] += add[cur];
            seg[cur << 1] += add[cur];
            add[cur] = 0;
        }
    }
    void pushUp(int cur) {
        seg[cur] = max(seg[cur << 1], seg[cur << 1 | 1]);
    }
    void build(int L, int R, int cur) {
        seg[cur] = add[cur] = 0;
        if (L == R) {
            return;
        }
        int mid = (L + R) >> 1;
        build(lson);
        build(rson);
        pushUp(cur);
    }
    void upDate(int be, int en, LL val, int L, int R, int cur) {
        if (L >= be && R <= en) {
            seg[cur] += val;
            add[cur] += val;
            return;
        }
        pushDown(cur);
        int mid = (L + R) >> 1;
        if (be <= mid) upDate(be, en, val, lson);
        if (en > mid) upDate(be, en, val, rson);
        pushUp(cur);
    }
    void work() {
        da.clear();
        int n;
        scanf("%d", &n);
        da.push_back(-inf);
        da.push_back(-inf);
        da.push_back(-inf);
        for (int i = 1; i <= n; ++i) {
            scanf("%d%d%d%d%d", &L[i], &R[i], &a[i], &b[i], &c[i]);
            L[i] *= 2;
            R[i] *= 2;
            da.push_back(L[i]);
            da.push_back(L[i] + 1);
            da.push_back(R[i] + 1);
            da.push_back(R[i]);
        }
        sort(da.begin(), da.end());
        int mx = 0;
        for (int i = 1; i <= n; ++i) {
            L[i] = lower_bound(da.begin(), da.end(), L[i]) - da.begin();
            R[i] = lower_bound(da.begin(), da.end(), R[i]) - da.begin();
    //        cout << L[i] << " " << R[i] << endl;
            mx = max(mx, R[i] + 2);
        }
    //    cout << endl;
        build(root);
        for (int i = 1; i <= n; ++i) {
            upDate(1, L[i] - 1, c[i], root);
            upDate(L[i], R[i], a[i], root);
            upDate(R[i] + 1, mx, b[i], root);
        }
        printf("%I64d
    ", seg[1]);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code

    现在的方法是直接

  • 相关阅读:
    生成PDF文档
    2016 百度研发岗面试总结
    有趣的数
    2016阿里校招python研发面试
    python 快排,堆排,归并
    三种简单的排序写下贴上
    BestCoder Round #47 1003
    c++ 适配器
    微信公众平台-超级大赛问题汇总1
    正则表达式简单总结
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6341684.html
Copyright © 2011-2022 走看看