日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【BZOJ-3262】陌上花开 CDQ分治(3维偏序)

發布時間:2025/4/9 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ-3262】陌上花开 CDQ分治(3维偏序) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

3262: 陌上花開

Time Limit:?20 Sec??Memory Limit:?256 MB
Submit:?1439??Solved:?648
[Submit][Status][Discuss]

Description

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

Input

第一行為N,K (1 <= N <= 100,000, 1 <= K <= 200,000 ), 分別表示花的數量和最大屬性值。 以下N行,每行三個整數si, ci, mi (1 <= si, ci, mi <= K),表示第i朵花的屬性

Output

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

Sample Input

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 1

Sample Output

3
1
3
0
1
0
1
0
0
1

HINT

1 <= N <= 100,000, 1 <= K <= 200,000

Source

樹套樹 CDQ分治

Solution

by CA

和Mokia一樣,考慮排序來處理掉一維,然后另一維分治,第三維套上數據結構

首先按s為第一關鍵字,c、m第二、三關鍵字排序,然后c維分治,對m維建樹狀數組。

CDQ(l,r)表示[l,r]中對任意的[l,r]中的x貢獻。所以用[l,mid]更新對[mid+1,r]中各元素的貢獻。

對c為第一關鍵字再排序,然后得到[l,mid],[mid+1,r]都是以c維從小到大排序的,把[l,mid]中的x,[mid+1,r]中的y,所有x.c<=y.c的x在他的m上+1,直到x.c>y.c,然后我們Query(y.m)就能得到對y的貢獻

統計完還原。

要注意的是:這樣有序的分治,我們發現當存在x、y,滿足x.s==y.s&&x.c==y.c&&x.m==y.m時,顯然排序時靠前的那個,統計答案時會少一個,所以我們需要在分治前去重,額外記錄一個個數即可。

Code

#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int read() {int x=0,f=1; char ch=getchar();while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}return x*f; } #define MAXN 100010 #define MAXK 200010 int N,K,tp,rank[MAXN]; struct FlowersNode {int s,c,m,n,id,rk;bool operator < (const FlowersNode & A) const{return s==A.s? (c==A.c? m<A.m:c<A.c):s<A.s; } }f[MAXN],F[MAXN]; bool cmp(FlowersNode A,FlowersNode B) {return A.c==B.c? A.m<B.m:A.c<B.c;} namespace BIT {int tree[MAXK];inline int lowbit(int x) {return x&-x;}inline void Change(int pos,int D) {for (int i=pos; i<=K; i+=lowbit(i)) tree[i]+=D;}inline int Query(int pos) {int re=0; for (int i=pos; i; i-=lowbit(i)) re+=tree[i]; return re;} } using namespace BIT; void CDQ(int l,int r) {if (l==r) {F[l].rk+=F[l].n-1; return;}int mid=(l+r)>>1;CDQ(l,mid); CDQ(mid+1,r);sort(F+l,F+mid+1,cmp); sort(F+mid+1,F+r+1,cmp); // for (int i=l; i<=r; i++) printf("%d %d %d %d %d\n",F[i].s,F[i].c,F[i].m,F[i].rk,F[i].n);int pos=l;for (int i=mid+1; i<=r; F[i].rk+=Query(F[i].m),i++)for (int j=pos; j<=mid && F[j].c<=F[i].c; j++,pos++)Change(F[j].m,F[j].n);for (int i=l; i<=pos-1; i++) Change(F[i].m,-F[i].n);sort(F+l,F+r+1,cmp); } bool compare(FlowersNode A,FlowersNode B) {return (A.s==B.s)&&(A.c==B.c)&&(A.m==B.m);} int main() {N=read(); K=read();for (int i=1; i<=N; i++) f[i].s=read(),f[i].c=read(),f[i].m=read(),f[i].rk=f[i].n=1;sort(f+1,f+N+1);for (int i=1; i<=N; i++) if (compare(f[i],F[tp])) F[tp].n++; else F[++tp]=f[i];CDQ(1,tp);for (int i=1; i<=tp; i++) rank[F[i].rk]+=F[i].n;for (int i=1; i<=N; i++) printf("%d\n",rank[i]);return 0; }

?

轉載于:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5862552.html

總結

以上是生活随笔為你收集整理的【BZOJ-3262】陌上花开 CDQ分治(3维偏序)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。