HDU4742----Pinball Game 3D(三维LIS、CDQ分治)

题意:三维空间内 n个小球,对应坐标(x,y,z)。输出LIS的长度以及方案数。

首先可以先按x排序,先降低一维,然后 剩下y 、z,在y上进行CDQ分治,按y的大小用前面的更新后面的。z方向离散化之后用树状数组维护就可以了。

  1 #include <set>
  2 #include <map>
  3 #include <cmath>
  4 #include <ctime>
  5 #include <queue>
  6 #include <stack>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstdlib>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 using namespace std;
 15 typedef unsigned long long ull;
 16 typedef long long ll;
 17 const int inf = 0x3f3f3f3f;
 18 const double eps = 1e-8;
 19 const int maxn = 1e5+10;
 20 const int mod = 1 << 30;
 21 struct Ball
 22 {
 23     int x,y,z,idx;
 24     bool operator < (const Ball &rhs)const
 25     {
 26         return x < rhs.x || (x == rhs.x && y < rhs.y) || (x == rhs.x && y == rhs.y && z < rhs.z);
 27     }
 28 } ball[maxn],tmpball[maxn];
 29 struct DP
 30 {
 31     int len,cnt;
 32     DP(){}
 33     DP(int _len,int _cnt):
 34         len(_len),cnt(_cnt) {}
 35 } dp[maxn],c[maxn];
 36 int vec[maxn],idx;
 37 inline int lowbit (int x)
 38 {
 39     return x & -x;
 40 }
 41 inline void update (DP &dp1, DP &dp2)
 42 {
 43     if (dp1.len < dp2.len)
 44         dp1 = dp2;
 45     else if (dp1.len == dp2.len)
 46         dp1.cnt += dp2.cnt;
 47 }
 48 inline void modify(int x,DP &d)
 49 {
 50     while (x <= idx)
 51     {
 52         update(c[x],d);
 53         x += lowbit(x);
 54     }
 55 }
 56 DP query(int x)
 57 {
 58     DP ans = DP (0,0);
 59     while (x)
 60     {
 61         update(ans,c[x]);
 62         x -= lowbit(x);
 63     }
 64     return ans;
 65 }
 66 inline void CLR(int x)
 67 {
 68     while (x <= idx)
 69     {
 70         c[x] = DP(0,0);
 71         x += lowbit(x);
 72     }
 73 }
 74 void CDQ (int l, int r)
 75 {
 76     if (l == r)
 77         return ;
 78     int mid = (l + r) >> 1;
 79     CDQ (l, mid);
 80     for (int i = l; i <= r; i++)
 81     {
 82         tmpball[i] = ball[i];
 83         tmpball[i].x = 0;
 84     }
 85    sort(tmpball+l,tmpball+r+1);
 86     for (int i = l; i <= r; i++)
 87     {
 88         if (tmpball[i].idx <= mid)
 89         {
 90             modify(tmpball[i].z,dp[tmpball[i].idx]);
 91         }
 92         else
 93         {
 94             DP tmp = query(tmpball[i].z);
 95             tmp.len++;
 96             update(dp[tmpball[i].idx],tmp);
 97         }
 98     }
 99     for (int i = l; i <= r; i++)
100     {
101         if (tmpball[i].idx <= mid)
102         {
103             CLR(tmpball[i].z);
104         }
105     }
106     CDQ (mid+1, r);
107 }
108 int main(void)
109 {
110 #ifndef ONLINE_JUDGE
111     freopen("in.txt","r",stdin);
112 #endif
113     int T, n;
114     scanf ("%d",&T);
115     while (T--)
116     {
117         scanf ("%d",&n);
118         for (int i = 1; i <= n; i++)
119         {
120             scanf ("%d%d%d",&ball[i].x, &ball[i].y, &ball[i].z);
121             vec[i-1] = ball[i].z;
122         }
123         sort (ball+1, ball+n+1);
124         sort (vec,vec+n);
125         idx = unique(vec,vec+n) - vec;
126         for (int i = 1; i <= n ; i++)
127         {
128             ball[i].z = lower_bound(vec,vec+idx,ball[i].z) - vec + 1;
129             ball[i].idx = i;
130             dp[i] = DP(1,1);
131         }
132         CDQ(1,n);
133         DP ans = DP(0,0);
134         for (int i = 1; i <= n ;i++)
135         {
136             update(ans,dp[i]);
137         }
138         printf("%d %d\n",ans.len, ans.cnt % mod);
139     }
140     return 0;
141 }

 

posted @ 2014-12-11 12:28  PlasticSpirit  阅读(902)  评论(0编辑  收藏  举报