3262: 陌上花开
3262: 陌上花开
分析
三维偏序问题。CDQ分治+树状数组。
首先没注意如何输出,就只直接把f[i]输出了,调啊调......然后没注意是小于等于又调啊调......最后没有特判相同的,看了题解才知道......
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 5 inline int read() { 6 int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; 7 for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; 8 } 9 10 const int N = 100100; 11 int ans[N],d[N],n,m; 12 struct Node{ 13 int x,y,z,cnt,ans; 14 bool operator < (const Node &a) const { 15 if (x == a.x && y == a.y) return z < a.z; 16 if (x == a.x) return y < a.y; 17 return x < a.x; 18 } 19 }A[N],B[N]; 20 struct BIT{ 21 int sum[N<<1]; 22 void update(int p,int v) { 23 for (; p<=m; p+=p&(-p)) sum[p] += v; 24 } 25 int query(int p) { 26 int ans = 0; 27 for (; p; p-=p&(-p)) ans += sum[p]; 28 return ans; 29 } 30 int clear(int p) { 31 for (; p<=m&&sum[p]; p+=p&(-p)) sum[p] = 0; 32 } 33 }bit; 34 35 void CDQ(int L,int R) { 36 if (L == R) {A[L].ans += A[L].cnt - 1;return ;} 37 int M = (L + R) >> 1; 38 CDQ(L,M); 39 CDQ(M+1,R); 40 int i = L,j = M + 1,k = L; 41 while (i <= M && j <= R) { 42 if (A[i].y <= A[j].y ) { // 对y进行排序,y相同时,z最初已经排好了。 43 bit.update(A[i].z,A[i].cnt); 44 B[k++] = A[i++]; 45 } 46 else { 47 A[j].ans += bit.query(A[j].z); 48 B[k++] = A[j++]; 49 } 50 } 51 while (i <= M) B[k++] = A[i++]; 52 while (j <= R) { 53 A[j].ans += bit.query(A[j].z); 54 B[k++] = A[j++]; 55 } 56 for (i=L; i<=R; ++i) { 57 bit.clear(A[i].z); 58 A[i] = B[i]; 59 } 60 } 61 int main() { 62 n = read(),m = read(); 63 for (int i=1; i<=n; ++i) { 64 A[i].x = read(),A[i].y = read(),A[i].z = read(),A[i].cnt = 1; 65 } 66 sort(A+1,A+n+1); 67 int tot = 1; 68 for (int i=2; i<=n; ++i) { // 去除相同的元素。 69 if (A[i].x == A[tot].x && A[i].y == A[tot].y && A[i].z == A[tot].z) A[tot].cnt ++; 70 else A[++tot] = A[i]; 71 } 72 73 CDQ(1,tot); 74 for (int i=1; i<=tot; ++i) ans[A[i].ans] += A[i].cnt; 75 for (int i=0; i<n; ++i) printf("%d\n",ans[i]); 76 return 0; 77 }