hdu 5618 Jam's problem again (cdq分治+BIT,三维偏序)
题意:
If two point such as (xi,yi,zi) and (xj,yj,zj) xi≥xj yi≥yj zi≥zj, the bigger one level add 1
问每个point的level是多少。
思路:
cdq分治,先去重并统计相同的点的数量,需要注意要记录原id对应到了哪个新id
/* ***********************************************
Author :111qqz
Created Time :2017年10月10日 星期二 19时53分38秒
File Name :5618.cpp
************************************************ */
1#include <cstdio>
2#include <cstring>
3#include <iostream>
4#include <algorithm>
5#include <vector>
6#include <queue>
7#include <set>
8#include <map>
9#include <string>
10#include <cmath>
11#include <cstdlib>
12#include <ctime>
13#define PB push_back
14#define fst first
15#define sec second
16#define lson l,m,rt<<1
17#define rson m+1,r,rt<<1|1
18#define ms(a,x) memset(a,x,sizeof(a))
19typedef long long LL;
20#define pi pair < int ,int >
21#define MP make_pair
1using namespace std;
2const double eps = 1E-8;
3const int dx4[4]={1,0,0,-1};
4const int dy4[4]={0,-1,1,0};
5const int inf = 0x3f3f3f3f;
6const int N=1E5+7;
7int n;
8struct point
9{
10 int x,y,z;
11 int id;
12 int cnt,sum;
13 void input( int _id)
14 {
15 scanf("%d %d %d",&x,&y,&z);
16 id=_id;
17 }
18 bool operator < (const point &b)const
19 {
20 if (x!=b.x) return x<b.x;
21 if (y!=b.y) return y<b.y;
22 return z<b.z;
23 }
24 bool operator !=(const point &b)const
25 {
26 return x!=b.x||y!=b.y||z!=b.z;
27 }
28}p[N];
29struct BIT
30{
31 int n,t[N];
32 void init( int _n)
33 {
34 n = _n;
35 ms(t,0);
36 }
37 inline int lowbit(int x){ return x&(-x);}
38 void update( int x,int delta)
39 {
40 for ( int i = x ; i <= n ; i+=lowbit(i)) t[i] +=delta;
41 }
42 int Sum( int x)
43 {
44 int ret = 0 ;
45 for ( int i = x ; i >=1 ; i-=lowbit(i)) ret+=t[i];
46 return ret;
47 }
48}bit;
49bool cmpcdq(point a,point b){return a.y<b.y;}
50bool cmpid(point a,point b){return a.id < b.id;}
51void cdq( int l,int r)
52{
53 if (l==r) return;
54 int mid = (l+r)>>1;
55 cdq(l,mid);
56 cdq(mid+1,r);
57 sort(p+l,p+mid+1,cmpcdq);
58 sort(p+mid+1,p+r+1,cmpcdq);
59 int j = l;
60 for ( int i = mid + 1 ; i <= r ; i++)
61 {
62 for ( ; j <= mid && p[j].y <= p[i].y ; j++) bit.update(p[j].z,p[j].cnt);
63 p[i].sum+=bit.Sum(p[i].z);
64 }
65 for ( int i = l ; i < j ; i++) bit.update(p[i].z,-p[i].cnt);
66}
67int tot;
68int ans[N];
69int id[N]; //记录原id对应到了哪个新id
70int main()
71{
72 #ifndef ONLINE_JUDGE
73 freopen("./in.txt","r",stdin);
74 #endif
75 int T;
76 scanf("%d",&T);
77 while (T--)
78 {
79 tot=0;
80 ms(p,0); //多组数据orz
81 scanf("%d",&n);
82 bit.init(N-1);
83 for ( int i = 1 ; i <= n ; i++) p[i].input(i);
84 int cnt = 0;
85 sort(p+1,p+n+1);
86 for ( int i = 1 ; i <= n ; i++)
87 {
88 cnt++;
89 if (p[i]!=p[i+1])
90 {
91 p[i].cnt = cnt;
92 id[p[i].id]=tot+1;
93 p[++tot]=p[i];
94 p[tot].id = tot;
95 cnt=0;
96 }
97 else
98 {
99 id[p[i].id] = tot+1;
100 }
1 }
2 cdq(1,tot);
3 //for ( int i = 1 ; i <= n ; i++) ans[id[p[i].id]] = p[i].sum ;
4 //for ( int i = 1 ; i <= n ; i++) printf("%d\n",ans[i]);
1 sort(p+1,p+tot+1,cmpid);
2 for ( int i = 1 ; i <= n ; i++) printf("%d\n",p[id[i]].sum+p[id[i]].cnt-1);
3 }
4 #ifndef ONLINE_JUDGE
5 fclose(stdin);
6 #endif
7 return 0;
8}