Edu41

基本情况

D卡太久了,第一次搞计算几何没经验

D. Pair Of Lines

Problem - D - Codeforces

思路不难,重要的是以后计算这种叉乘一定要开longlong

E. Tufurama

Problem - E - Codeforces

  1. 我们维护一个存储下标数据的树状数组,先将 \(1\sim n\) 插入树状数组。

  2. \(a\) 表示原数组,\(b\) 表示按照 \(a_i\) 排序后的数组。

  3. 我们从 \(1\) 开始统计,直到 \(n\),统计时:

    • \(i\) 删除,不能把自己算进去。

    • 为了排除 \(a_j < i\) 的部分,可以从前往后扫描 \(b\),一直删,直到 \(b_{\text{cur}} \geq i\)

      因为 \(b\) 单调不下降,所以 \(i\) 都用不着了, \(i + 1\) 也用不着了。

    • 调查 \(a_i \geq j\) 的部分,调用 \(\text{query}(a_i)\) 即可。

    • 注意:排除的时候用 \(b\),这样就不用遍历整个 \(a\) 数组来排除 \(a_j < i\) 的部分;

      而询问的时候要用 \(a\),因为询问的是 \(a_i \geq j\) 的部分。

void solve() {
    int n;
    std::cin >> n;
    std::vector<int> a(n);
    for (auto& x : a) std::cin >> x, --x;
    std::vector<std::pair<int, int>> b(n);
    for (int i = 0; i < n; i++) {
        b[i].first = a[i], b[i].second = i;
    }
    Fenwick<i64> T(n);
    for (int i = 0; i < n; i++) {
        T.add(i, 1);
    }
    std::sort(all(b));
    int cur(0);
    i64 ans(0);
    std::vector<bool> del(n);
    for (int i = 0; i < n; i++) {
        if (not del[i]) {//先把当前删了
            del[i] = true;
            T.add(i, -1);
        }
        while(cur < n and b[cur].first < i) {//把所有不符合条件(a_j < i)的都删了
            if (not del[b[cur].second]) {
                del[b[cur].second] = true;
                T.add(b[cur].second, -1);
            }
            cur++;
        }
        ans += T.sum(std::min(n, a[i] + 1));//查找所有小于等于a_i的元素
    }
    std::cout << ans << '\n';
}
posted @ 2024-03-27 14:20  加固文明幻景  阅读(8)  评论(0编辑  收藏  举报