首页 > 代码库 > HDU4742----Pinball Game 3D(三维LIS、CDQ分治)

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_JUDGE111     freopen("in.txt","r",stdin);112 #endif113     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 }

 

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