【BZOJ2244】[SDOI2011]拦截导弹(CDQ分治)

题面

BZOJ

洛谷

题解

不难发现这就是一个三维偏序+\(LIS\)这样一个\(dp\)。

那么第一问很好求,直接\(CDQ\)分治之后\(dp\)就好了。

那么第二问呢?首先如果记一个方案数,显然就可以在转移的时候求出以每个点开头/结尾的\(LIS\)个数,这样子在算的时候前后乘一下再除掉全部的\(LIS\)数就是答案了。

说起来好简单啊,码起来就不一样了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 50500
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n;
struct Node{int h,v,i;}p[MAX];
int lb(int x){return x&(-x);}
int c[MAX];double w[MAX];
void add(int x,int v,double W)
{
while(x<=n)
{
if(v==c[x])w[x]+=W;
else if(v>c[x])c[x]=v,w[x]=W;
x+=lb(x);
}
}
int Query(int x){int ret=0;while(x)ret=max(ret,c[x]),x-=lb(x);return ret;}
double Query(int x,int v){double ret=0;while(x)ret+=(c[x]==v)?w[x]:0,x-=lb(x);return ret;}
int f[2][MAX];double g[2][MAX];
void clear(int x){while(x<=n)c[x]=w[x]=0,x+=lb(x);}
bool cmph(Node a,Node b){return a.h>b.h;}
bool cmpv(Node a,Node b){return a.v>b.v;}
bool cmpi(Node a,Node b){return a.i<b.i;}
void CDQ(int l,int r,int type)
{
if(l==r)return;
sort(&p[l],&p[r+1],cmpi);
if(type)reverse(&p[l],&p[r+1]);
int mid=(l+r)>>1;
CDQ(l,mid,type);
sort(&p[l],&p[mid+1],cmph);
sort(&p[mid+1],&p[r+1],cmph);
for(int i=mid+1,j=l;i<=r;++i)
{
while(j<=mid&&p[j].h>=p[i].h)
add(n+1-p[j].v,f[type][p[j].i],g[type][p[j].i]),++j;
int d=Query(n+1-p[i].v)+1;
if(d>f[type][p[i].i])f[type][p[i].i]=d,g[type][p[i].i]=Query(n+1-p[i].v,d-1);
else if(d==f[type][p[i].i])g[type][p[i].i]+=Query(n+1-p[i].v,d-1);
}
for(int i=l;i<=mid;++i)clear(n+1-p[i].v);
CDQ(mid+1,r,type);
}
int Sh[MAX],toth,Sv[MAX],totv;
int main()
{
n=read();
for(int i=1;i<=n;++i)p[i].h=read(),p[i].v=read(),p[i].i=i;
for(int i=1;i<=n;++i)Sh[++toth]=p[i].h;
sort(&Sh[1],&Sh[toth+1]);toth=unique(&Sh[1],&Sh[toth+1])-Sh-1;
for(int i=1;i<=n;++i)p[i].h=lower_bound(&Sh[1],&Sh[toth+1],p[i].h)-Sh;
for(int i=1;i<=n;++i)Sv[++totv]=p[i].v;
sort(&Sv[1],&Sv[totv+1]);totv=unique(&Sv[1],&Sv[totv+1])-Sv-1;
for(int i=1;i<=n;++i)p[i].v=lower_bound(&Sv[1],&Sv[totv+1],p[i].v)-Sv;
for(int i=1;i<=n;++i)f[0][i]=f[1][i]=g[0][i]=g[1][i]=1;
CDQ(1,n,0);
reverse(&p[1],&p[n+1]);
for(int i=1;i<=n;++i)p[i].v=n-p[i].v+1,p[i].h=n-p[i].h+1;
CDQ(1,n,1);
int ans=0;double sum=0;
for(int i=1;i<=n;++i)ans=max(ans,f[0][i]);
for(int i=1;i<=n;++i)if(f[0][i]==ans)sum+=g[0][i];
printf("%d\n",ans);
for(int i=1;i<=n;++i)
if(f[0][i]+f[1][i]-1!=ans)printf("0.000000 ");
else printf("%.6lf ",g[0][i]*g[1][i]/sum);
puts("");return 0;
}

【BZOJ2244】[SDOI2011]拦截导弹(CDQ分治)的更多相关文章

  1. [BZOJ2244][SDOI2011]拦截导弹 CDQ分治

    2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec  Memory Limit: 512 MB  Special Judge Description 某国为了防御敌国的导弹 ...

  2. BZOJ2244: [SDOI2011]拦截导弹(CDQ分治,二维LIS,计数)

    Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高 ...

  3. bzoj 2244: [SDOI2011]拦截导弹 cdq分治

    2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec  Memory Limit: 512 MBSec  Special JudgeSubmit: 237  Solved: ...

  4. BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)

    题意 略- 分析 就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i ...

  5. BZOJ 2244: [SDOI2011]拦截导弹 [CDQ分治 树状数组]

    传送门 题意:三维最长不上升子序列以及每个元素出现在最长不上升子序列的概率 $1A$了好开心 首先需要从左右各求一遍,长度就是$F[0][i]+F[1][i]-1$,次数就是$G[0][i]*G[1] ...

  6. BZOJ 2244 [SDOI2011]拦截导弹 ——CDQ分治

    三维偏序,直接CDQ硬上. 正反两次CDQ统计结尾的方案数,最后统计即可. #include <cstdio> #include <cstring> #include < ...

  7. BZOJ2244 [SDOI2011]拦截导弹 【cdq分治 + 树状数组】

    题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其 ...

  8. bzoj2244[SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 第$i$个导弹看成一个三元组$(i,h_i,v_i)$ 其实就是最长上升子序列的问题. 我们分 ...

  9. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

随机推荐

  1. Ionic app 通知在Moto 360 Watch上显示通知(2)

    在前一篇文章中,我们已经将Wtach的环境测试成功,下面进入我们自己消息的接收. 1.安装JPush插件在我们的App中,这个具体步骤可以参考 Ionic 安装JPush过程 2.在App上的登录模块 ...

  2. C#的RSA加密解密签名,就为了支持PEM PKCS#8格式密钥对的导入导出

    差点造了一整个轮子 .Net Framework 4.5 里面的RSA功能,并未提供简单对PEM密钥格式的支持(.Net Core有咩?),差点(还远着)造了一整个轮子,就为了支持PEM PKCS#8 ...

  3. QT 小总结

    遇到的问题: 1:在debug模式下可以顺利执行,但是换到release模式下没法执行了.会显示 exited with code 1 . 解决办法:把产生的release文件放到QT的bin库下,看 ...

  4. Vue Element Tabe Pager 分页方案

    表格和分页分离的,但是使用中,却是结合在一起的. 分析 有以下方式触发查询: mounted 加载数据. 查询按钮 加载数据. pager 变化加载数据 加载数据函数: loadData 问题 mou ...

  5. Centos7下关于系统用户密码规则-运维笔记

    针对Centos7下的系统用户的密码规则复杂度的设置,处于安全考虑,说明如下: 一.设置密码规则 1)密码长度.有效期 /etc/login.defs文件是当创建用户时的一些规划,比如创建用户时,是否 ...

  6. Centos6.9下RocketMQ3.4.6高可用集群部署记录(双主双从+Nameserver+Console)

    之前的文章已对RocketMQ做了详细介绍,这里就不再赘述了,下面是本人在测试和生产环境下RocketMQ3.4.6高可用集群的部署手册,在此分享下: 1) 基础环境 ip地址 主机名 角色 192. ...

  7. Nginx反向代理中使用proxy_redirect重定向url

    在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用proxy_redirect进行url重定向设置了.proxy_redirect功能比较强大,其作用是对 ...

  8. #个人博客作业week3——微软必应词典的使用

    产品的调研和评测 笔者使用的是win8的必应词典客户端. 首先打开客户端,用户界面的设计十分简洁,使用方便.但是词典主页与大多外语软件的设计相仿,例如有每日一句,每日阅读等模块,并没有令人感到新奇的地 ...

  9. SQL中常用函数

    SELECT CONVERT(varchar(100), GETDATE(), 23) AS  日期   结果:2017-01-05     select ISNULL(price,'0.0')   ...

  10. JAVA面对对象(四)——抽象类

    抽象类的作用类似“模板”,可以根据它的格式来修改.创建新的类:但是不能直接由抽象类创建对象只能通过抽象类派生出新的类,再由它来创建对象:抽象类的使用同样是单继承,即一个子类只能继承一个抽象类 抽象类的 ...