题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4742
题意:求3维的LIS。。
用分治算法搞得,参考了cxlove的题解。。
首先按照x排序,然后每个三元组一个编号1-n。接下来只要考虑y和z的值,假设[l,mid]区间已经求好,那么我们对[l,r]区间按照y排序,更新[mid+1,r]区间的最优值时,只要考虑z值了,用树状数组维护z的最长LIS,遇到[mid+1,r]区间的就更新。
1 //STATUS:C++_AC_1750MS_5348KB 2 #include <functional> 3 #include <algorithm> 4 #include <iostream> 5 //#include <ext/rope> 6 #include <fstream> 7 #include <sstream> 8 #include <iomanip> 9 #include <numeric> 10 #include <cstring> 11 #include <cassert> 12 #include <cstdio> 13 #include <string> 14 #include <vector> 15 #include <bitset> 16 #include <queue> 17 #include <stack> 18 #include <cmath> 19 #include <ctime> 20 #include <list> 21 #include <set> 22 #include <map> 23 using namespace std; 24 //#pragma comment(linker,"/STACK:102400000,102400000") 25 //using namespace __gnu_cxx; 26 //define 27 #define pii pair<int,int> 28 #define mem(a,b) memset(a,b,sizeof(a)) 29 #define lson l,mid,rt<<1 30 #define rson mid+1,r,rt<<1|1 31 #define PI acos(-1.0) 32 //typedef 33 typedef __int64 LL; 34 typedef unsigned __int64 ULL; 35 //const 36 const int N=100010; 37 const int INF=0x3f3f3f3f; 38 const int MOD=100000,STA=8000010; 39 const LL LNF=1LL<<60; 40 const double EPS=1e-8; 41 const double OO=1e15; 42 const int dx[4]={-1,0,1,0}; 43 const int dy[4]={0,1,0,-1}; 44 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; 45 //Daily Use ... 46 inline int sign(double x){return (x>EPS)-(x<-EPS);} 47 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;} 48 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;} 49 template<class T> inline T lcm(T a,T b,T d){return a/d*b;} 50 template<class T> inline T Min(T a,T b){return a<b?a:b;} 51 template<class T> inline T Max(T a,T b){return a>b?a:b;} 52 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);} 53 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);} 54 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));} 55 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));} 56 //End 57 58 struct Node{ 59 int x,y,z,id; 60 bool operator <(const Node& a)const{ 61 return x!=a.x?x<a.x:(y!=a.y?y<a.y:z<a.z); 62 } 63 }a[N],b[N]; 64 pii f[N],bit[N]; 65 int z[N]; 66 int T,n,m; 67 68 #define lowbit(x) (x&-x) 69 70 inline void update(pii& a,pii& b) 71 { 72 if(b.first>a.first)a=b; 73 else if(b.first==a.first){ 74 a.second+=b.second; 75 } 76 } 77 78 inline void add(int x,pii& b) 79 { 80 for(;x<=m;x+=lowbit(x)){ 81 update(bit[x],b); 82 } 83 } 84 85 inline pii query(int x) 86 { 87 pii ret=make_pair(0,0); 88 for(;x>0;x-=lowbit(x)){ 89 update(ret,bit[x]); 90 } 91 return ret; 92 } 93 94 inline void clear(int x) 95 { 96 for(;x<=m;x+=lowbit(x)){ 97 bit[x]=make_pair(0,0); 98 } 99 } 100 101 void solve(int l,int r) 102 { 103 if(l==r)return; 104 int i,j,k,mid,cnt=0; 105 mid=(l+r)>>1; 106 solve(l,mid); 107 for(i=l;i<=r;i++){ 108 b[cnt]=a[i]; 109 b[cnt++].x=0; 110 } 111 sort(b,b+cnt); 112 for(i=0;i<cnt;i++){ 113 if(b[i].id<=mid){ 114 add(b[i].z,f[b[i].id]); 115 } 116 else { 117 pii t=query(b[i].z); 118 t.first++; 119 update(f[b[i].id],t); 120 } 121 } 122 for(i=0;i<cnt;i++){ 123 if(b[i].id<=mid) 124 clear(b[i].z); 125 } 126 solve(mid+1,r); 127 } 128 129 int main() 130 { 131 // freopen("in.txt","r",stdin); 132 int i,j; 133 pii ans; 134 scanf("%d",&T); 135 while(T--) 136 { 137 scanf("%d",&n); 138 for(i=0;i<n;i++){ 139 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); 140 z[i]=a[i].z; 141 } 142 143 sort(a,a+n); 144 sort(z,z+n); 145 m=unique(z,z+n)-z; 146 for(i=0;i<n;i++){ 147 f[i]=make_pair(1,1); 148 a[i].id=i; 149 a[i].z=lower_bound(z,z+m,a[i].z)-z+1; 150 } 151 solve(0,n-1); 152 ans=make_pair(0,0); 153 for(i=0;i<n;i++){ 154 update(ans,f[i]); 155 } 156 157 printf("%d %d ",ans.first,ans.second); 158 } 159 return 0; 160 }