bzoj3262 陌上花開 cdq分治

2021-08-14 12:16:32 字數 1433 閱讀 8920

有n朵花,每朵花有三個屬性:花形(s)、顏色(c)、氣味(m),又三個整數表示。現要對每朵花評級,一朵花的級別是它擁有的美麗能超過的花的數量。定義一朵花a比另一朵花b要美麗,當且僅當sa>=sb,ca>=cb,ma>=mb。顯然,兩朵花可能有同樣的屬性。需要統計出評出每個等級的花的數量。

1 <= n <= 100,000, 1 <= k <= 200,000

第一道,三維偏序問題。我實在太弱辣做不出省選題,只好來刷別的了

如果是二維的話可以考慮按x排序樹狀陣列統計y的答案

所謂cdq分治就是對於一系列的操作,我們分成(l,mid)和(mid+1,r)兩個區間分別處理,最後統計左區間操作對右區間的影響

在這題就是先按x排序,遞迴得到左右區間後y就是有序的了,而左區間的x一定小於右區間的x,這樣就能直接用樹狀陣列統計答案。注意統計完之後要清空不然會影響下一次統計

打起來像歸併似的

#include 

#include

#include

#define rep(i,st,ed) for (int i=st;i<=ed;++i)

#define fill(x,t) memset(x,t,sizeof(x))

#define lowbit(x) ((x)&(-(x)))

const

int n=400005;

struct flowert[n],q[n];

int ans[n],c[n],n,m,cnt=0;

int read()

bool cmp1(flower a,flower b)

}int get(int x)

return ret;

}void cdq(int l,int r)

int mid=(l+r)/2;

cdq(l,mid); cdq(mid+1,r);

for (int i=l,j=mid+1;j<=r;j++)

t[j].ans+=get(t[j].z);

}for (int i=l,j=mid+1;j<=r;j++)

}int i=l,j=mid+1,k=l;

while (i<=mid&&j<=r)

while (i<=mid) q[k++]=t[i++];

while (j<=r) q[k++]=t[j++];

for (i=l;i<=r;i++) t[i]=q[i];

}int main(void)

std:: sort(q+1,q+n+1,cmp1);

rep(i,1,n)

cdq(1,cnt);

rep(i,1,cnt) ans[t[i].ans]+=t[i].cnt;

rep(i,0,n-1) printf("%d\n", ans[i]);

return

0;}

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 又三個整數表示。現要對每朵花評級,一朵花的級別是它擁有的美麗能超過的花的數量...