Pinball Game 3D

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1137    Accepted Submission(s): 477

Problem Description
RD is a smart boy and excel in pinball game. However, playing common 2D pinball game for a great number of times results in accumulating tedium. 



Recently, RD has found a new type of pinball game, a 3D pinball game. The 3D pinball game space can be regarded as a three dimensional coordinate system containing N balls. A ball can be considered as a point. At the beginning, RD made a shot and hit a ball.
The ball hit by RD will move and may hit another ball and the “another ball” may move and hit another another ball, etc. But once a ball hit another ball, it will disappear.



RD is skilled in this kind of game, so he is able to control every ball's moving direction. But there is a limitation: if ball A's coordinate is (x1,y1,z1) and ball B's coordinate is (x2,y2,z2), then A can hit B only if x1 <= x2 and y1 <= y2 and z1 <= z2.



Now, you should help RD to calculate the maximum number of balls that can be hit and the number of different shooting schemes that can achieve that number. Two schemes are different if the sets of hit balls are not the same. The order doesn't matter.
 
Input
The first line contains one integer T indicating the number of cases.

In each case, the first line contains one integer N indicating the number of balls. 

The next N lines each contains three non-negative integer (x, y, z), indicating the coordinate of a ball. 

The data satisfies T <= 3, N <= 105, 0 <= x, y, z <= 230, no two balls have the same coordinate in one case.
 
Output
Print two integers for each case in a line, indicating the maximum number of balls that can be hit and the number of different shooting schemes. As the number of schemes can be quite large, you should output this number mod 230.
 
Sample Input
2
3
2 0 0
0 1 0
0 1 1
5
3 0 0
0 1 0
0 0 1
0 2 2
3 3 3
 
Sample Output
2 1
3 2
问题是求三维的LIS问题。LIS,即最长递增子序列。显然是用动态规划来求解的
一维的情况,可以直接两个for循环,进行DP。但是如果数据有1e5,暴力循环效率是O(n^2*(n+1)/2),
所以可以用一些数据结构优化一下,比如单调队列,树状数组等。
树状数组最擅长的是快速的求前缀和,同时也可以求前缀和最值。
下面三维的情况要复杂一点。首先,要找到比这个点小的点,然后在这些点中进行DP
这就属于三维偏序的问题,对于三维偏序,一般都是降维处理
可以一维排序,二维CDQ分治,三维树状数组,
这里,CDQ分治,要先处理左半边,然后处理左半边对右半边的影响,再处理右半边。
树状数组里面插入DP状态,
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
using namespace std; const int maxn=1e5;
const int INF=0x7FFFFFFF;
const int mod = 1 << 30 ; struct Node
{
int x,y,z;
int id,z2;
}a[maxn+5],b[maxn+5]; int n,e,d[maxn+5];
int cmp(Node a,Node b)
{
if(a.x==b.x&&a.y==b.y)
return a.z<b.z;
else if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
int cmp2(Node a,Node b)
{
return a.z<b.z;
}
struct node
{
int len;
int num;
}dp[maxn+5],c[maxn+5]; int lowbit(int x)
{
return x&(-x);
}
void update(node &term1,node term2)
{
if(term1.len<term2.len)
{
term1=term2;
}
else if(term1.len==term2.len)
term1.num+=term2.num;
} void insert(int x,node y)
{
for(int i=x;i<=e;i+=lowbit(i))
{
update(c[i],y);
}
}
node sum(int x)
{
node p;
for(int i=x;i>=1;i-=lowbit(i))
{
update(p,c[i]);
}
return p;
}
void del(int x)
{
for(int i=x;i<=e;i+=lowbit(i))
{
c[i].len=0;
c[i].num=0;
}
}
void fun(int l,int r)
{
if(l==r)
{ return;
}
int mid=(l+r)>>1;
fun(l,mid);
for(int i=l;i<=r;i++)
{
b[i]=a[i];
b[i].x=0;
}
sort(b+l,b+r+1,cmp);
for(int i=l;i<=r;i++)
{
if(b[i].id<=mid)
{
insert(b[i].z,dp[b[i].id]);
}
else
{
node temp=sum(b[i].z);
if(dp[b[i].id].len<temp.len+1)
{
dp[b[i].id].len=temp.len+1;
dp[b[i].id].num=temp.num;
}
else if(dp[b[i].id].len==temp.len+1)
dp[b[i].id].num+=temp.num;
}
}
for(int i=l;i<=r;i++)
{
if(b[i].id<=mid)
del(b[i].z);
}
fun(mid+1,r); }
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
e=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
d[i]=a[i].z; } sort(a+1,a+n+1,cmp);
sort(d+1,d+1+n),e=unique(d+1,d+1+n)-d; for(int i=1;i<=n;i++)
{
a[i].id=i;
dp[i].len=1;
dp[i].num=1;
a[i].z=lower_bound(d+1,d+1+e,a[i].z)-d;
c[i].len=0;
c[i].num=0;
} fun(1,n);
node ans;
ans.len=0;
ans.num=0;
for(int i=1;i<=n;i++)
update(ans,dp[i]);
printf("%d %d\n",ans.len,ans.num%mod);
}
return 0;
}

 

HDU 4247 Pinball Game 3D(cdq 分治+树状数组+动态规划)的更多相关文章

  1. Hdu4742-Pinball Game 3D(cdq分治+树状数组)

    Problem Description RD is a smart boy and excel in pinball game. However, playing common 2D pinball ...

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

    题目链接:hdu_4742_Pinball Game 3D 题意: 给你n个点,让你求三维的LIS,并且求出有多少种组合能达到LIS. 题解: 求三维的LIS,典型的三维偏序问题,x排序,解决一维,c ...

  3. 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组

    [BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...

  4. BZOJ 1176 Mokia CDQ分治+树状数组

    1176: [Balkan2007]Mokia Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 821[Submit][St ...

  5. 【bzoj3262】陌上花开 CDQ分治+树状数组

    题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...

  6. 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组

    题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...

  7. BZOJ 2683 简单题 cdq分治+树状数组

    题意:链接 **方法:**cdq分治+树状数组 解析: 首先对于这道题,看了范围之后.二维的数据结构是显然不能过的.于是我们可能会考虑把一维排序之后还有一位上数据结构什么的,然而cdq分治却可以非常好 ...

  8. LOJ3146 APIO2019路灯(cdq分治+树状数组)

    每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...

  9. BZOJ 4553 [Tjoi2016&Heoi2016]序列 ——CDQ分治 树状数组

    考虑答案的构成,发现是一个有限制条件的偏序问题. 然后三个维度的DP,可以排序.CDQ.树状数组各解决一维. #include <map> #include <cmath> # ...

随机推荐

  1. 安装cx_Oracle 遇到的杂项问题

    1. 解决方法: 将xc用户添加进sudousers 2.安装VMware Tools 更新 http://pubs.vmware.com/vsphere-50/index.jsp?topic=%2F ...

  2. ioc和aop的区别?

    ioc:控制反转(Inversion of Control,英文缩写为IoC)把创建对象的权利交给框架,是框架的重要特征,并非面向对象编程的专用术语.它包括依赖注入(Dependency Inject ...

  3. (转)sqlite3生成lib遇到的问题

    今天想用一用sqlite,但是下载后发现只有DLL,没有LIB,只能自己生成了.在H:/Program Files/Microsoft Visual Studio 8/VC/bin里面有个lib.ex ...

  4. c#后台访问接口

    直接上代码 后台代码 //接口地址string url = "http://spherefg.topsmoon.com:6666/restapi/Comment/SubmitCommentF ...

  5. tomcat server.xml docbase workdir

    在tomcat安装好后,只要把你的web项目copy到%TOMCAT_HOME%webapp下面就可以是使用啦!!其实还有种方法就是设定虚拟目录,即把项目的目录映射到tomcat中.这样做即可以不用重 ...

  6. Oracle从字符串资源中得到想要的数据分析

    [oracle]从字符串资源中得到想要的数据分析需求:订单分析,按照游戏,帐号级别,游戏帐号职业,区服,价格区间分析各款交易数据走势 .目标:订单表(order)处理分析:订单中可以直接读到的标示有游 ...

  7. C语言中文件目录(一正二反)斜杠

    正斜杠unix“/” linux,安卓,苹果都是 windows是两个反斜杠“\\”,但现在也兼容了可以使用正斜杠“/”

  8. linux shell判断脚本执行时传入了多少个参数,判断脚本参数个数,参数数量

    需求描述: 在写shell脚本的时候,会有这样的需求,脚本在执行的过程中是需要传入参数的,如果没有参数传递给脚本, 就会给出相应的脚本使用方法或者例子,告知,脚本后面应该加什么样的参数.所以呢,这里要 ...

  9. mybatis由浅入深day02_3一对多查询

    3 一对多查询 3.1 需求(查询订单及订单明细的信息) 查询订单及订单明细的信息. 3.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. ...

  10. Delphi的打开文件对话框-TOpenDialog

    1.TOpenDialog组件的典型用法 “打开”对话框是用TOpenDialog组件实现的,TOpenDialog组件是非可视组件. Filter属性用于设置文件过滤器,让对话框只列出特定类型的文件 ...