bzoj2244[SDOI2011]拦截导弹
http://www.lydsy.com/JudgeOnline/problem.php?id=2244
第$i$个导弹看成一个三元组$(i,h_i,v_i)$
其实就是最长上升子序列的问题。
我们分别求以第$i$个导弹为结尾的最长上升子序列的长度和个数,以及以第$i$个导弹为开头的最长上升子序列的长度和个数。
下面以求以第$i$个导弹为结尾的最长上升子序列的长度和个数为例。
记以第$i$个导弹结尾的最长上升子序列长度为$f[i]$,则:
$$f[i]=Max\{f[j]|j<i,h[j]\geq h[i],v[j]\geq v[i]\}+1$$
所以第1问就是三维偏序,用CDQ分治解决。
第一维由分治的时候左边小于右边保证;
第二维由排序保证;
第三维由数据结构保证;
看程序应该会比较好理解。
记以第$i$个导弹结尾的最长上升子序列长度为$g[i]$,则:
$$g[i]=\sum g[j](f[j]+1=f[i],j<i,h[j]\geq h[i],v[j]\geq v[i])$$
我们可以先按f排序,然后分层DP,还是用CDQ分治。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj using namespace std; typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef complex<DB> CP; #define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b) for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)
#define fi first
#define se second
#define m_p(a,b) make_pair(a,b)
#define p_b(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k)) template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;} inline int sgn(DB x){if(abs(x)<1e-)return ;return(x>)?:-;}
const DB Pi=acos(-1.0); int gint()
{
int res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
}
LL gll()
{
LL res=;bool neg=;char z;
for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
if(z==EOF)return ;
if(z=='-'){neg=;z=getchar();}
for(;z!=EOF && isdigit(z);res=res*+z-'',z=getchar());
return (neg)?-res:res;
} const int maxn=; int n,ny,nz;
struct Ta{int x,y,z,f,flag;DB g;}a[maxn+];
int bak[maxn+]; int f1[maxn+],f2[maxn+];
DB g1[maxn+],g2[maxn+];
int ans; bool cmpx(Ta a,Ta b){return a.x<b.x;}
bool cmpyx(Ta a,Ta b){return a.y!=b.y?a.y<b.y:a.x<b.x;}//注意y相同时,x小的在前面!!!
bool cmpf(Ta a,Ta b){return a.f<b.f;} #define lowbit(a) ((a)&(-a))
namespace TREE1
{
int tree[maxn+];
void update(int a,int v){for(;a<=n;a+=lowbit(a))upmax(tree[a],v);}
int ask(int a){int res=;for(;a>=;a-=lowbit(a))upmax(res,tree[a]);return res;}
void clear(int a){for(;a<=n;a+=lowbit(a))tree[a]=;}
}
void CDQf(int l,int r)
{
if(l==r){upmax(a[l].f,);return;}
int i,mid=(l+r)/;
CDQf(l,mid);
sort(a+l,a+r+,cmpyx);
re(i,l,r)if(a[i].x<=mid)TREE1::update(a[i].z,a[i].f);else upmax(a[i].f,TREE1::ask(a[i].z)+);
re(i,l,r)if(a[i].x<=mid)TREE1::clear(a[i].z);
sort(a+l,a+r+,cmpx);
CDQf(mid+,r);
} namespace TREE2
{
DB tree[maxn+];
void update(int a,DB v){for(;a<=n;a+=lowbit(a))tree[a]+=v;}
DB ask(int a){DB res=;for(;a>=;a-=lowbit(a))res+=tree[a];return res;}
void clear(int a){for(;a<=n;a+=lowbit(a))tree[a]=0.0;}
}
void CDQg(int l,int r)
{
if(l==r)return;
int i,mid=(l+r)/;
CDQg(l,mid);
sort(a+l,a+r+,cmpyx);
re(i,l,r)
{
if(a[i].x<=mid && a[i].flag) TREE2::update(a[i].z,a[i].g);
if(a[i].x>mid && !a[i].flag) a[i].g+=TREE2::ask(a[i].z);
}
re(i,l,r)if(a[i].x<=mid && a[i].flag) TREE2::clear(a[i].z);
sort(a+l,a+r+,cmpx);
CDQg(mid+,r);
} int tmpx[maxn+];
void solve()
{
int i,j,l1,r1,l2,r2;
re(i,,n)a[i].f=,a[i].g=0.0;
CDQf(,n);
sort(a+,a+n+,cmpf);
for(l1=r1=;r1<n && a[r1+].f==a[l1].f;r1++);
re(i,l1,r1)a[i].g=;
for(;r1<n;l1=l2,r1=r2)
{
for(l2=r2=r1+;r2<n && a[r2+].f==a[l2].f;r2++);
re(i,l1,r1)a[i].flag=;
sort(a+l1,a+r2+,cmpx);
re(i,l1,r2)tmpx[i]=a[i].x,a[i].x=i;
CDQg(l1,r2);
re(i,l1,r2)a[i].x=tmpx[i];
sort(a+l1,a+r2+,cmpf);
re(i,l1,r1)a[i].flag=;
}
sort(a+,a+n+,cmpx);
} int ans1;
DB ans2; int main()
{
freopen("bzoj2244.in","r",stdin);
freopen("bzoj2244.out","w",stdout);
int i;
n=gint();
re(i,,n)a[i].x=i,a[i].y=gint(),a[i].z=gint(); ny=;
re(i,,n)bak[++ny]=a[i].y;
sort(bak+,bak+ny+);
ny=unique(bak+,bak+ny+)-bak-;
re(i,,n)a[i].y=ny-(lower_bound(bak+,bak+ny+,a[i].y)-bak)+;
nz=;
re(i,,n)bak[++nz]=a[i].z;
sort(bak+,bak+nz+);
nz=unique(bak+,bak+nz+)-bak-;
re(i,,n)a[i].z=nz-(lower_bound(bak+,bak+nz+,a[i].z)-bak)+; solve();
re(i,,n)f1[i]=a[i].f,g1[i]=a[i].g; re(i,,n)a[i].x=n-a[i].x+,a[i].y=ny-a[i].y+,a[i].z=nz-a[i].z+;
re(i,,n/)swap(a[i],a[n-i+]); solve();
re(i,,n)a[i].x=n-a[i].x+,a[i].y=ny-a[i].y+,a[i].z=nz-a[i].z+;
re(i,,n/)swap(a[i],a[n-i+]);
re(i,,n)f2[i]=a[i].f,g2[i]=a[i].g; re(i,,n)upmax(ans1,f1[i]);
re(i,,n)if(f1[i]==ans1)ans2+=g1[i];
PF("%d\n",ans1);
re(i,,n)if(f1[i]+f2[i]-!=ans1 || sgn(ans2)==)PF("0.00000 ");else PF("%0.5lf ",g1[i]*g2[i]/ans2);
return ;
}
bzoj2244[SDOI2011]拦截导弹的更多相关文章
- [BZOJ2244][SDOI2011]拦截导弹 CDQ分治
		
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MB Special Judge Description 某国为了防御敌国的导弹 ...
 - BZOJ2244 [SDOI2011]拦截导弹  【cdq分治 + 树状数组】
		
题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其 ...
 - BZOJ2244: [SDOI2011]拦截导弹(CDQ分治,二维LIS,计数)
		
Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高 ...
 - bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹
		
http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...
 - 【BZOJ2244】[SDOI2011]拦截导弹(CDQ分治)
		
[BZOJ2244][SDOI2011]拦截导弹(CDQ分治) 题面 BZOJ 洛谷 题解 不难发现这就是一个三维偏序+\(LIS\)这样一个\(dp\). 那么第一问很好求,直接\(CDQ\)分治之 ...
 - bzoj 2244: [SDOI2011]拦截导弹 cdq分治
		
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 237 Solved: ...
 - 【LG2481】[SDOI2011]拦截导弹
		
[LG2481][SDOI2011]拦截导弹 题面 洛谷 题解 可以看出第一问就是一个有关偏序的\(LIS\),很显然可以用\(CDQ\)优化 关键在于第二问 概率\(P_i=\) \(总LIS数\) ...
 - P2487 [SDOI2011]拦截导弹
		
题目 P2487 [SDOI2011]拦截导弹 做\(SDOI\)有种想评黑的感觉,果然还是太弱了 做法 独立写(调)代码三个小时祭 简化题目:求二维最长不上升子序列及每个点出现在最长不上升子序列概率 ...
 - BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治
		
2244: [SDOI2011]拦截导弹 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截 ...
 
随机推荐
- SQL给查询结果加序号
			
情境:在用delphi7编程时,想要给查询出的结果一个编号,比方有一万条结果,就自己主动从1编号到10000 显示数据时用的是DBGrid控件,可是它的第一列无法非常好的显示编号,找了非常多方法都不能 ...
 - apache在windows上开启gzip的方法
			
环境搭建好之后,默认并没有开启gzip功能.需要修改apache的httpd.conf配置文件进行开启.开启方法如下:1. httpd.conf中打开deflate_Module和headers_Mo ...
 - 《UNIX网络编程》之select IO
			
select 函数的原理 select 管理者 用select来管理多个IO 一旦其中的一个或者多个IO检测到我们所感兴趣的事件, select 函数返回,返回值为检测到的事件个数 然后,遍历事件,进 ...
 - DecimalFormat用法
			
DecimalFormat用法 DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字. DecimalFormat 包含一个模式 和一组符号 符号含义: ...
 - 用Hexo搭建属于自己的Blog
			
什么是Hexo 简单的来说,Hexo是一款基于Node.JS的静态博客框架,官方给它的描述是"A fast, simple & powerful blog framework&quo ...
 - JPush 极光推送 消息推送 实例
			
简介 官网:https://www.jpush.cn/ 极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,让开发者积极地保持与用户的连接,从而提高用户活跃度 ...
 - Oracle 空间管理
			
表空间:组数据文件的一种途径 分类: 目录表空间(sysaux) 常表空间(system) 系统临时表空间(temp) 用户临时表空间(user) undo表空间 创建表空间: //表空间名为name ...
 - TextView过长显示省略号, TextView文字中间加横线
			
1.TextView显示的内容过长时自动显示省略号: 省略号的位置:android:ellipsize="end" 省略号在结尾android:ellipsize=" ...
 - ASP.Net页面间传值
			
一.目前在ASP.NET中页面传值共有这么几种方式: 1.表单提交, <form action= "target.aspx" method = "post&qu ...
 - 表被占用住,提示资源正忙的处理方式。kill掉表的操作。
			
1)查找死锁的进程: SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l ...