zoukankan      html  css  js  c++  java
  • [Bzoj3262]陌上花开(CDQ分治&&树状数组||树套树)

    题目链接

    题目就是赤裸裸的三维偏序,所以用CDQ+树状数组可以比较轻松的解决,但是还是树套树好想QAQ

    CDQ+树状数组

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const ll maxn = 200000 + 100;
    struct node {
        int a, b, c, num, val;
    }q[maxn], w[maxn];
    bool cmp(node x, node y) {
        return x.a == y.a ? (x.b == y.b ? x.c < y.c : x.b < y.b) : x.a < y.a;
    }
    int sum[maxn], ans[maxn];
    int n, k;
    int lowbit(int x) {
        return x & -x;
    }
    void add(int x, int val) {
        while (x <= k) {
            sum[x] += val;
            x += lowbit(x);
        }
    }
    int query(int x) {
        int ans = 0;
        while (x > 0) {
            ans += sum[x];
            x -= lowbit(x);
        }
        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 L = l, R = mid + 1, cnt = l;
        while (L <= mid && R <= r) {
            if (w[L].b <= w[R].b)add(w[L].c, w[L].num), q[cnt++] = w[L++];
            else w[R].val += query(w[R].c), q[cnt++] = w[R++];
        }
        while (L <= mid)add(w[L].c, w[L].num), q[cnt++] = w[L++];
        while (R <= r)w[R].val += query(w[R].c), q[cnt++] = w[R++];
        for (int i = l; i <= mid; i++)add(w[i].c, -w[i].num);
        for (int i = l; i <= r; i++)w[i] = q[i];
    }
    int main() {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++)
            scanf("%d%d%d", &q[i].a, &q[i].b, &q[i].c), q[i].num = 1;
        sort(q + 1, q + 1 + n, cmp);
        int cnt = 1;
        w[1] = q[1];
        for (int i = 2; i <= n; i++) {
            if (q[i].a == w[cnt].a&&q[i].b == w[cnt].b&&q[i].c == w[cnt].c)w[cnt].num++;
            else w[++cnt] = q[i];
        }
        CDQ(1, cnt);
        for (int i = 1; i <= cnt; i++)
            ans[w[i].val + w[i].num - 1] += w[i].num;
        for (int i = 0; i < n; i++)
            printf("%d
    ", ans[i]);
    }

    树套树(树状数组套线段树)

    因为空间有限,线段树要动态开点且要写成链表QAQ。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef unsigned long long ull;
     5 const ll maxn = 200000 + 100;
     6 struct node {
     7     int a, b, c, num, val;
     8 }q[maxn], w[maxn];
     9 bool cmp(node x, node y) {
    10     return x.a == y.a ? (x.b == y.b ? x.c < y.c : x.b < y.b) : x.a < y.a;
    11 }
    12 int n, k;
    13 int ans[maxn];
    14 struct seg {
    15     struct node {
    16         int  val;
    17         node *ls, *rs;
    18         node() { val = 0; ls = rs = NULL; }
    19     };
    20     node *root;
    21     seg() {
    22         root = NULL;
    23     }
    24     void update(node *&x, int pos, int val, int l, int r) {
    25         if (!x)x = new node();
    26         if (l == r) {
    27             x->val += val;
    28             return;
    29         }
    30         int mid = l + r >> 1;
    31         if (pos <= mid)update(x->ls, pos, val, l, mid);
    32         else update(x->rs, pos, val, mid + 1, r);
    33         x->val = (x->ls ? x->ls->val : 0) + (x->rs ? x->rs->val : 0);
    34     }
    35     int query(node *x, int L, int R, int l, int r) {
    36         if (!x)return 0;
    37         if (L <= l && r <= R)
    38             return x->val;
    39         int mid = l + r >> 1, ans = 0;
    40         if (L <= mid)ans += query(x->ls, L, R, l, mid);
    41         if (R > mid)ans += query(x->rs, L, R, mid + 1, r);
    42         return ans;
    43     }
    44 }T[maxn];
    45 int lowbit(int x) {
    46     return x & -x;
    47 }
    48 void add(int x, int q, int val) {
    49     while (x <= k) {
    50         T[x].update(T[x].root, q, val, 1, k);
    51         x += lowbit(x);
    52     }
    53 }
    54 int query(int x, int q) {
    55     int ans = 0;
    56     while (x > 0) {
    57         ans += T[x].query(T[x].root, 1, q, 1, k);
    58         x -= lowbit(x);
    59     }
    60     return ans;
    61 }
    62 int main() {
    63     scanf("%d%d", &n, &k);
    64     for (int i = 1; i <= n; i++)
    65         scanf("%d%d%d", &q[i].a, &q[i].b, &q[i].c), q[i].num = 1;
    66     sort(q + 1, q + 1 + n, cmp);
    67     int cnt = 1;
    68     w[1] = q[1];
    69     for (int i = 2; i <= n; i++) {
    70         if (q[i].a == w[cnt].a&&q[i].b == w[cnt].b&&q[i].c == w[cnt].c)w[cnt].num++;
    71         else w[++cnt] = q[i];
    72     }
    73     for (int i = 1; i <= cnt; i++) {
    74         add(w[i].b, w[i].c, w[i].num);
    75         int p = query(w[i].b, w[i].c);
    76         ans[p] += w[i].num;
    77     }
    78     for (int i = 1; i <= n; i++)
    79         printf("%d
    ", ans[i]);
    80 }
  • 相关阅读:
    webpack + vue 向本地后端发送http请求跨域问题
    用FileReader对象从本地读取文件
    oninput与onchange比较
    height: 100% 无效问题
    关于html布局
    圣诞节给自己的犒劳
    django学习之——模版
    django学习之——我的 Hello World
    django学习之——创建项目
    python and pycharm and django 环境配置
  • 原文地址:https://www.cnblogs.com/sainsist/p/11436860.html
Copyright © 2011-2022 走看看