hdu_4742_Pinball Game 3D(cdq分治+树状数组)

题目链接:hdu_4742_Pinball Game 3D

题意:

给你n个点,让你求三维的LIS,并且求出有多少种组合能达到LIS。

题解:

求三维的LIS,典型的三维偏序问题,x排序,解决一维,cdq分治y,解决一维,树状数组维护z,解决一维。

注意,cdq中sort不要调用太多,不然会被卡常。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;i++)
 3 using namespace std;
 4 typedef pair<int,int>P;
 5 
 6 const int N=1e5+7,mod=1<<30;
 7 int t,n,hsh_ed,hsh[N];
 8 P sum[N],dp[N];
 9 
10 struct node
11 {
12     int x,y,z,id;
13     bool operator <(const node & b)const{return x<b.x||(x==b.x&&y<b.y)||(x==b.x&&y==b.y&&z<b.z);}
14 }a[N],b[N];
15 
16 inline void up(P &a,P b)
17 {
18     if(a.first==b.first)a.second+=b.second;
19     else if(a.first<b.first)a=b;
20 }
21 inline void add(int x,P c){while(x<=hsh_ed)up(sum[x],c),x+=x&-x;}
22 inline P ask(int x){P an=P(0,0);while(x)up(an,sum[x]),x-=x&-x;return an;}
23 inline void back(int x){while(x<=hsh_ed)sum[x]=P(0,0),x+=x&-x;}
24 
25 void cdq(int l,int r)
26 {
27     if(l==r)return;
28     int mid=l+r>>1;
29     cdq(l,mid);
30     F(i,l,r)b[i]=a[i],b[i].x=0;
31     sort(b+l,b+1+r);
32     F(i,l,r)
33     {
34         if(b[i].id<=mid)add(b[i].z,dp[b[i].id]);
35         else
36         {
37             P now=ask(b[i].z);
38             if(now.first+1>dp[b[i].id].first)dp[b[i].id]=P(now.first+1,now.second);
39             else if(now.first+1==dp[b[i].id].first)dp[b[i].id].second+=now.second;
40         }
41     }        
42     F(i,l,r)if(b[i].id<=mid)back(b[i].z);
43     cdq(mid+1,r);
44 }
45 
46 int main()
47 {
48     scanf("%d",&t);
49     while(t--)
50     {
51         scanf("%d",&n),hsh_ed=0;
52         F(i,1,n)
53         {
54             scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
55             hsh[i]=a[i].z;
56         }
57         sort(a+1,a+1+n);
58         sort(hsh+1,hsh+1+n),hsh_ed=unique(hsh+1,hsh+1+n)-hsh;
59         F(i,1,n)
60         {
61             dp[i]=P(1,1),a[i].id=i;
62             a[i].z=lower_bound(hsh+1,hsh+1+hsh_ed,a[i].z)-hsh;
63         }
64         cdq(1,n);
65         P ans=P(0,0);
66         F(i,1,n)up(ans,dp[i]);
67         printf("%d %d\n",ans.first,ans.second%mod);
68     }
69     return 0;
70 }
View Code

 

posted @ 2016-11-22 17:35  bin_gege  阅读(149)  评论(0)    收藏  举报