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
",ans[i]);
76     return 0;
77 }
原文地址:https://www.cnblogs.com/mjtcn/p/9231069.html