• 洛谷P3810 陌上花开(CDQ分治)


    洛谷P3810 陌上花开

    传送门

    题解:

    CDQ分治模板题。
    一维排序,二维归并,三维树状数组。
    核心思想是分治,即计算左边区间对右边区间的影响。
    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 200005;
    int n, k, m;
    struct node{
        int x, y, z, id, w;
        bool operator < (const node &A)const{
            if(A.x == x && A.y == y) return z < A.z;
            else if(A.x == x) return y < A.y;
            return x < A.x;
        }
    }a[N], b[N], d[N];
    int ans[N], c[N], cnt[N];
    vector <int> v1, v2[N] ;
    int lowbit(int x) {
        return x& (-x);
    }
    void add(int x, int v) {
        for(int i = x; i < N; i += lowbit(i)) c[i] += v;
    }
    int query(int x) {
        int ans = 0;
        for(int i = x; i; i -= lowbit(i)) ans += c[i];
        return ans;
    }
    void cdq(int l, int r) {
        if(l == r) return ;
        int mid = (l + r) >> 1;
        cdq(l, mid), cdq(mid + 1, r) ;
        int t1 = l, t2 = mid + 1;
        for(int i = l; i <= r; i++) {
            if((t1 <= mid && a[t1].y <= a[t2].y) || t2 > r) {
                add(a[t1].z, a[t1].w);
                b[i] = a[t1++];
            } else {
                cnt[a[t2].id] += query(a[t2].z);
                b[i] = a[t2++];
            }
        }
        for(int i = l; i <= mid; i++) add(a[i].z, -a[i].w);
        for(int i = l; i <= r; i++) a[i] = b[i];
    }
    int main() {
        ios::sync_with_stdio(false); cin.tie(0);
        cin >> n >> k;
        for(int i = 1; i <= n; i++) {
            cin >> a[i].x >> a[i].y >> a[i].z;
            a[i].id = i;
        }
        sort(a + 1, a + n + 1);
        int num = 1;
        for(int i = 2; i <= n + 1; i++) {
            if(a[i].x != a[i - 1].x || a[i].y != a[i - 1].y || a[i].z != a[i - 1].z) {
                d[++m] = a[i - 1];
                d[m].w = num;
                num = 1;
                v2[a[i - 1].id] = v1;
                v1.clear();
            } else {
                num++;
                v1.push_back(a[i - 1].id) ;
            }
        }
        for(int i = 1; i <= m; i++) a[i] = d[i];
        cdq(1, m);
        for(int i = 1; i <= m; i++) {
            int sz = v2[a[i].id].size();
            for(auto v : v2[a[i].id]) cnt[v] += cnt[a[i].id] + sz;
            cnt[a[i].id] += sz;
        }
        for(int i = 1; i <= n; i++) ans[cnt[i]]++;
        for(int i = 0; i < n; i++) cout << ans[i] << '
    ';
        return 0;
    }
    /*
    3 4
    1 2 3
    1 2 3
    2 1 3
    */
    
    
  • 相关阅读:
    深度优先和广度优先
    ajax<转>
    display:inline-block后会有间隙
    css样式多了个分号
    回答
    return false作用
    824. Goat Latin
    7. Reverse Integer
    48. Rotate Image
    9. Palindrome Number
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/11335689.html
Copyright © 2020-2023  润新知