BZOJ3262 陌上花開 CDQ分治

2022-09-14 16:15:25 字數 1603 閱讀 5830

有n朵花,每朵花有三個屬性:花形(s)、顏色(c)、氣味(m),用三個整數表示。

現在要對每朵花評級,一朵花的級別是它擁有的美麗能超過的花的數量。

定義一朵花a比另一朵花b要美麗,當且僅sa>=sb,ca>=cb,ma>=mb。

顯然,兩朵花可能有同樣的屬性。需要統計出評出每個等級的花的數量。

第一行為n,k (1 <= n <= 100,000, 1 <= k <= 200,000 ), 分別表示花的數量和最大屬性值。

以下n行,每行三個整數si, ci, mi (1 <= si, ci, mi <= k),表示第i朵花的屬性

包含n行,分別表示評級為0...n-1的每級花的數量。

10 3

3 3 3

2 3 3

2 3 1

3 1 1

3 1 2

1 3 1

1 1 2

1 2 2

1 3 2

1 2 131

3010

1001

正好借這個題的題解總結一下我對cdq的理解

順便借這個題學了一下一直沒碰過的樹狀陣列……

首先對於三維偏序$(a,b,c)$,我們可以以a為關鍵字進行sort,

這樣陣列中的a就是有序的,每次分治當前區間我們只考慮左半邊對右半邊的貢獻,這樣就可以消除a的影響qaq

再觀察一下現在要解決的問題,統計$b_<=b_$且$c_<=c[i]$

如果我們把b當做陣列下標,c當陣列下標裡的值的話,可以想到什麼?逆序對!不過這裡是個順序對就是了

所以就是第一維使其sort有序,第二維分治的時候歸併排序使其有序,第三維用樹狀陣列進行統計

注意要去重,否則如果a=b,那麼(a,b)(b,a)本來都是可以的,但分治的時候不去重我們只能考慮進去一種

1 #include2 #include3 #include4 #include5

#define n (200000+1000)

6using

namespace

std;78

intn,k,emm,top,c[n],ans[n];910

int lowbit(int x)

11int add(int x,int delta)

12int sum(int x)

1314

struct

node

1523

}a[n],t[n];

2425

void cdq(int l,int

r)26

36for (int i=l; i<=mid; ++i) add(a[i].c,-a[i].size);

37for (int i=l; i<=r; ++i) a[i]=t[i];38}

3940

intmain()

4153 n=top;

54 cdq(1

,n);

55for (int i=1; i<=n; ++i) ans[a[i].ans+a[i].size-1]+=a[i].size;

56for (int i=0; i"

%d\n

",ans[i]);

57 }

BZOJ 3262 陌上花開 CDQ

time limit 20 sec memory limit 256 mb submit 2457 solved 1098 submit status discuss 有n朵花,每朵花有三個屬性 花形 s 顏色 c 氣味 m 又三個整數表示。現要對每朵花評級,一朵花的級別是它擁有的美麗能超過的花的數...

BZOJ3262 陌上花開 CDQ分治

對第一關鍵字排序,分治每朵花,合併的時候通過歸併左右的花的第二關鍵字,將值插入樹狀陣列中求值。對於相同的花,先進行預處理即可。include bits stdc h define lowbit x x x using namespace std const int n 100005,m 200005...

bzoj 3262 陌上花開(cdq分治)

time limit 20 sec memory limit 256 mb submit 1431 solved 644 submit status discuss 有n朵花,每朵花有三個屬性 花形 s 顏色 c 氣味 m 又三個整數表示。現要對每朵花評級,一朵花的級別是它擁有的美麗能超過的花的數量...