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 }

 

你可能感兴趣的:(game)