• Codeforces Beta Round #12 (Div 2 Only) D. Ball 树状数组查询后缀、最值


    http://codeforces.com/problemset/problem/12/D

    这里的BIT查询,指的是查询[1, R]或者[R, maxn]之间的最值,这样就够用了。

    设三个权值分别是b[1], b[2], b[2];

    首先,先把b[1]值离散化,离散成一个个id,那么只能是在id比较大的地方找了。然后把b[2]排序,倒序查询,也就是先查询最大的,当然它是没可能自杀的,因为它已经最大了,然后查询完后,把它压进bit后,以后在bit查询,就不需要管b[2]了,因为在bit里面的b[2]永远都是较大者,其实这是一个常用的方法啦。hack点是相同的值不能提前更新,细节看代码 + 慢慢debug

    现在说说bit的作用,bit维护的是b[3],因为我们已经离散化b[1]了,那么每一个元素的下标就相当于离散化的b[1],所以加进去BIT的时候用id做下标即可。bit维护后缀最大值。

    hack点的意思是,假如你的a[i].b[2] == a[j].b[2],那么不能在查询a[j]前提前把a[i]加入bit,因为bit查询默认是b[2]成立的,但是提前更新了的话,不成立。

    #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>
    #include <stack>
    const int maxn = 5e5 + 20;
    int c[maxn], en;
    int lowbit(int x) {
        return x & (-x);
    }
    void upDate(int pos, int val) {
        while (pos) {
            c[pos] = max(c[pos], val);
            pos -= lowbit(pos);
        }
    }
    int ask(int pos) {
        int ans = -1;
        while (pos <= en) {
            ans = max(ans, c[pos]);
            pos += lowbit(pos);
        }
        return ans;
    }
    struct Node {
        int a[5], id;
    }a[maxn];
    stack<int> st;
    bool cmp0(struct Node a, struct Node b) {
        return a.a[1] < b.a[1];
    }
    bool cmp1(struct Node a, struct Node b) {
        return a.a[2] < b.a[2];
    }
    
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[1]);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[2]);
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i].a[3]);
        sort(a + 1, a + 1 + n, cmp0);
        en = 1;
        a[1].id = en;
        for (int i = 2; i <= n; ++i) {
            if (a[i].a[1] == a[i - 1].a[1]) {
                a[i].id = en;
            } else a[i].id = ++en;
        }
        en += 2;
        memset(c, -1, sizeof c);
        sort(a + 1, a + 1 + n, cmp1);
    //    for (int i = 1; i <= n; ++i) {
    //        cout << a[i].a[1] << " " << a[i].a[2] << " " << a[i].a[3] << " " << a[i].id << endl;
    //    }
        st.push(n);
        int ans = 0;
        for (int i = n - 1; i >= 1; --i) {
            if (a[i].a[2] == a[i + 1].a[2]) {
                st.push(i);
                int res = ask(a[i].id + 1);
                ans += res > a[i].a[3];
            } else {
                while (!st.empty()) {
                    int res = st.top();
                    st.pop();
                    upDate(a[res].id, a[res].a[3]);
                }
                int res = ask(a[i].id + 1);
                ans += res > a[i].a[3];
                st.push(i);
    //            upDate(a[i].id, a[i].a[3]);
            }
        }
        cout << ans << endl;
    }
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        work();
        return 0;
    }
    View Code
  • 相关阅读:
    使用 Vite 提供的常见模板创建项目
    git 上传空目录,并忽略该空目录中产生的文件变更
    SCL
    Python中时间相关的操作
    rpm的使用
    configparser
    安全随机数
    sqlite3
    多线程threading
    python小杂记
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6690522.html
Copyright © 2020-2023  润新知