国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

HDU - 5618 CDQ分治 + 樹(shù)狀數(shù)組

2019-11-10 22:22:26
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

題意:

給出n個(gè)有序?qū)?a,,b,c),對(duì)于每個(gè)(ai,bi,ci)找到滿足aj <=ai,bj<=bi,cj<=ci的有序?qū)τ卸嗌賯€(gè)。

思路:

典型的三維偏序問(wèn)題,可以用CDQ分治來(lái)解決。首先將有序?qū)Π凑誥的大小排序,這樣對(duì)區(qū)間[L,R)進(jìn)行分治的時(shí)候就可以默認(rèn)左半部分[L,M)的a要小于等于右半部份[M,R)的a。按照CDQ分治的思想,先遞歸處理左右兩個(gè)部分的子問(wèn)題,然后處理左半部分對(duì)于右半部份的影響,就這題來(lái)說(shuō),就是對(duì)左右兩部分按照b的大小排序,按照歸并排序的寫(xiě)法先進(jìn)入臨時(shí)數(shù)組tmp的有序?qū)一定不大于之后進(jìn)的。那么現(xiàn)在關(guān)鍵是處理c,因?yàn)橛衏存在不能直接計(jì)數(shù),注意到所有數(shù)字的大小只有1e5,這時(shí)候考慮用樹(shù)狀數(shù)組求和來(lái)統(tǒng)計(jì)c的個(gè)數(shù),就如同求逆序?qū)Φ淖鞣ㄒ粯印?duì)于左半部分的每一個(gè)有序?qū)υ趤?lái)更新樹(shù)狀數(shù)組,右半部份的每個(gè)有序?qū)?lái)查詢(xún)樹(shù)狀數(shù)組,從而計(jì)數(shù)。這題還有幾個(gè)地方需要注意:1.定義Query大小關(guān)系的時(shí)候,要記得包括小于等于的情況。2.排序的時(shí)候不能只按照a的大小排序,還要按照先b后c確定優(yōu)先級(jí),因?yàn)檫@樣才能保證右邊區(qū)間的有序?qū)δ苷业剿斜葍?yōu)先級(jí)他小的。3.按照上面的做法,如果有m個(gè)完全一樣的有序?qū)?a,b,c),這m個(gè)有序?qū)λ蟮慕Y(jié)果受到位置的影響并不一樣,因?yàn)榕旁诤竺娴目梢越y(tǒng)計(jì)前面的,而前面的卻沒(méi)有統(tǒng)計(jì)后面的,所以一開(kāi)始排序排在m個(gè)中最后的那個(gè)有序?qū)Σ攀沁@m個(gè)有序?qū)餐拇鸢浮?.記得在每一次的分治都要清空樹(shù)狀數(shù)組。

代碼:

#include <bits/stdc++.h>using namespace std;const int MAXN = 1e5 + 10;const int MAXC = 1e5 + 10;const int MAXQ = MAXN;int maxc;struct BIT {    int C[MAXC];    int lowbit(int x) {        return x & -x;    }    void add(int x, int y) {        while (x <= MAXC) {            C[x] += y;            x += lowbit(x);        }    }    int sum(int x) {        int res = 0;        while (x) {            res += C[x];            x -= lowbit(x);        }        return res;    }     void clr(int x){         while (x <= MAXC) {             if (C[x]) C[x] = 0; else break;             x += lowbit(x);          }     }}bit;struct Query {    int id, b, c;    bool Operator < (const Query &rhs) const {        return b == rhs.b ? c <= rhs.c : b < rhs.b;    // 優(yōu)先級(jí)一定要考慮到等于的情況    }}que[MAXQ], tmp[MAXQ];int ans[MAXN];void cdq(int l, int r) {    if (r - l <= 1) return;    int m = (l + r) >> 1;    cdq(l, m); cdq(m, r);    int p = l, q = m, cnt = 0;    while (p < m && q < r) {        if (que[p] < que[q]) {            bit.add(que[p].c, 1);            tmp[cnt++] = que[p++];        }        else {            ans[que[q].id] += bit.sum(que[q].c);            tmp[cnt++] = que[q++];        }    }    while (p < m) tmp[cnt++] = que[p++];    while (q < r) {        ans[que[q].id] += bit.sum(que[q].c);        tmp[cnt++] = que[q++];    }    for (int i = 0; i < cnt; i++) {        bit.clr(tmp[i].c);        que[i + l] = tmp[i];    }}struct node {    int id, a, b, c;    bool operator < (const node &rhs) const {        return a == rhs.a ? (b == rhs.b ? c < rhs.c : b < rhs.b) : a < rhs.a;   // 考慮位置因素,要按照先a再b后c的優(yōu)先級(jí)排序    }}arr[MAXN];int main() {    //freopen("in.txt", "r", stdin);    int T;    scanf("%d", &T);    while (T--) {        int n;        scanf("%d", &n);        for (int i = 0; i < n; i++) {            scanf("%d%d%d", &arr[i].a, &arr[i].b, &arr[i].c);            arr[i].id = i;        }        sort (arr, arr + n);        maxc = 0;        for (int i = 0; i < n; i++) {            que[i] = (Query) {arr[i].id, arr[i].b, arr[i].c};            maxc = max(maxc, arr[i].c);        }        memset(ans, 0, sizeof(ans));        cdq(0, n);        for (int i = n - 1; i >= 0; i--) {            if (arr[i].a == arr[i + 1].a && arr[i].b == arr[i + 1].b && arr[i].c == arr[i + 1].c)                ans[arr[i].id] = ans[arr[i + 1].id];        // 倒著更新相同有序?qū)Φ拇鸢?       }        for (int i = 0; i < n; i++)            PRintf("%d/n", ans[i]);    }    return 0;}
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 闸北区| 平乡县| 长寿区| 东安县| 新竹县| 望谟县| 定安县| 当阳市| 河池市| 册亨县| 那坡县| 桐柏县| 长葛市| 乐清市| 樟树市| 西乌珠穆沁旗| 应城市| 辽中县| 来凤县| 富阳市| 灵台县| 平泉县| 沾化县| 阿拉尔市| 钟祥市| 自贡市| 呼图壁县| 寿光市| 上蔡县| 驻马店市| 西丰县| 顺昌县| 资源县| 石阡县| 楚雄市| 沙坪坝区| 安图县| 麦盖提县| 罗平县| 贵州省| 平原县|