题意:三维空间内 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 }
时间: 2024-11-06 07:13:15