题目链接: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]区间的就更新。
//STATUS:C++_AC_1750MS_5348KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End struct Node{
int x,y,z,id;
bool operator <(const Node& a)const{
return x!=a.x?x<a.x:(y!=a.y?y<a.y:z<a.z);
}
}a[N],b[N];
pii f[N],bit[N];
int z[N];
int T,n,m; #define lowbit(x) (x&-x) inline void update(pii& a,pii& b)
{
if(b.first>a.first)a=b;
else if(b.first==a.first){
a.second+=b.second;
}
} inline void add(int x,pii& b)
{
for(;x<=m;x+=lowbit(x)){
update(bit[x],b);
}
} inline pii query(int x)
{
pii ret=make_pair(,);
for(;x>;x-=lowbit(x)){
update(ret,bit[x]);
}
return ret;
} inline void clear(int x)
{
for(;x<=m;x+=lowbit(x)){
bit[x]=make_pair(,);
}
} void solve(int l,int r)
{
if(l==r)return;
int i,j,k,mid,cnt=;
mid=(l+r)>>;
solve(l,mid);
for(i=l;i<=r;i++){
b[cnt]=a[i];
b[cnt++].x=;
}
sort(b,b+cnt);
for(i=;i<cnt;i++){
if(b[i].id<=mid){
add(b[i].z,f[b[i].id]);
}
else {
pii t=query(b[i].z);
t.first++;
update(f[b[i].id],t);
}
}
for(i=;i<cnt;i++){
if(b[i].id<=mid)
clear(b[i].z);
}
solve(mid+,r);
} int main()
{
// freopen("in.txt","r",stdin);
int i,j;
pii ans;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=;i<n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
z[i]=a[i].z;
} sort(a,a+n);
sort(z,z+n);
m=unique(z,z+n)-z;
for(i=;i<n;i++){
f[i]=make_pair(,);
a[i].id=i;
a[i].z=lower_bound(z,z+m,a[i].z)-z+;
}
solve(,n-);
ans=make_pair(,);
for(i=;i<n;i++){
update(ans,f[i]);
} printf("%d %d\n",ans.first,ans.second);
}
return ;
}