# 「BZOJ」「3262」陌上花开

CDQ分治

WA ：在solve时，对y、z排序以后，没有处理「y、z相同」的情况，也就是说可能（1，2，3）这个点被放到了（2，2，3）的后面，也就是统计答案在前，插入该点在后……也就没有统计到！

 1 #include<cstdio>
2 #include<cstring>
3 #include<cstdlib>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7
8 const int N = 200010;
9 int n,k;
10 struct node{
11     int x,y,z,id;
12 }a[100010], b[100010];
13 bool operator != (node a,node b){
14     return a.x != b.x || a.y != b.y || a.z != b.z;
15 }
16 bool operator < (node a,node b){
17     return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z);
18 }
19 bool cmp(node a,node b){
20     return a.y < b.y || (a.y == b.y && a.z < b.z) || (a.y == b.y && a.z == b.z && a.id < b.id);
21 }
22 int ans[N], rank[N], num[N];
23
24 int val[N], vis[N], times;
25 inline int lowbit(int x){
26     return x & (-x);
27 }
28 void add(int pos, int v){
29     for(int i = pos; i <= k; i += lowbit(i))
30         if (vis[i] == times) val[i] += v;
31         else val[i] = v, vis[i] = times;
32 }
33 int query(int pos){
34     int ans = 0;
35     for(int i = pos; i; i -= lowbit(i))
36         if (vis[i] == times)
37             ans += val[i];
38     return ans;
39 }
40
41 void solve(int l,int r){
42     int mid = l + r >> 1;
43     if (l < mid) solve(l, mid);
44     sort(a + l, a + r + 1, cmp);
45     times ++;
46     for(int i = l; i <= r; i ++)
47         if (a[i].id <= mid) add(a[i].z, num[a[i].id]);
48         else rank[a[i].id] += query(a[i].z);
49     sort(a + l, a + r + 1);
50     if (mid + 1 < r) solve(mid + 1, r);
51 }
52 int main(){
53     freopen("3262.in", "r", stdin);
54     freopen("3262.out", "w", stdout);
55     scanf("%d%d",&n,&k);
56     for(int i = 1; i <= n; i ++)
57         scanf("%d%d%d",&a[i].x, &a[i].y, &a[i].z);
58     sort(a + 1, a + n + 1);
59     for(int i = 1; i <= n; i ++) b[i] = a[i];
60     int cnt = 0;
61     for(int i = 1; i <= n; i ++)
62         if (b[i] != b[i - 1]) a[++ cnt] = b[i], num[cnt] = 1;
63         else num[cnt] ++;
64     for(int i = 1; i <= cnt; i ++) a[i].id = i, rank[i] = num[i] - 1;
65 //    for(int i = 1; i <= cnt; i ++) printf("%d %d %d num = %d\n",a[i].x, a[i].y, a[i].z, num[i]);
66     solve(1, cnt);
67 //    for(int i = 1; i <= cnt; i ++) printf("rank[%d] = %d\n",i,rank[i]);
68     for(int i = 1; i <= cnt; i ++)
69         ans[rank[i]] += num[i];
70     for(int i = 0; i < n; i ++) printf("%d\n",ans[i]);
71     return 0;
72 }
View Code

posted @ 2016-07-02 21:00  Tunix  阅读(...)  评论(...编辑  收藏