http://www.lydsy.com/JudgeOnline/problem.php?id=2244

每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数

pre_len [i] 表示以i结尾的最长不下降子序列的长度

pre_sum[i] 表示对应长度下的方案数

suf_len[i] 表示以i开头的最长不下降子序列长度

suf_sum[i] 表示对应长度下的方案数

若已有了这4个数组

设最长上升子序列长度=mx

那么 如果pre_len[i]+suf_len[i] - 1==mx,那么第i枚导弹在最长上升子序列上

而且在pre_sum[i]*suf_sum[i] 个最长上升子序列上

如何获取这四个数组?

这是一个三维偏序问题,CDQ分治

若i后面可以接j

第一维:i的出现时间<j的出现时间

第二维:i的高度>=j的高度

第三维:i的速度>=j的速度

具体实现:

排序第一维,CDQ过程中排序解决第二维,树状数组解决第三维

对于第三维,要离散化

树状数组查询的是<=查询位置的信息,即用它来求最长不下降子序列更方便

所以在解决以i为开头的最长不上升子序列的时候

将第二维取负,第三维i变成n-i+1

在解决以i为开始的最长不上升子序列的时候

将第一维取负

对CDQ分治更进一步的理解:

之前写CDQ分治做数据结构题的时候,

写的是先解决左边对右边的贡献,在递归两边

但是这道题,要先递归左边,再解决左边对右边的贡献,再递归右边

因为最长不下降子序列 左边更新右边的时候,左边的所有不是等价的

即也需要用左边更新之后的结果来更新右边

而像那种修改查询题,左边的修改对左边查询的影响和对右边查询的影响是等价的

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 50001 #define lowbit(x) ( x&-x ) int n;
int h[N],v[N];
int tot,has[N]; struct node
{
int x,y,z;
int len;
double sum;
}e[N]; int c[N];
double d[N]; int pre_len[N],suf_len[N];
double pre_sum[N],suf_sum[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} bool cmdy(node p,node q)
{
if(p.y==q.y) return p.z<q.z;
return p.y<q.y;
} bool cmdx(node p,node q)
{
return p.x<q.x;
} void change(int pos,int len,double sum)
{
while(pos<=n)
{
if(len>c[pos])
{
c[pos]=len;
d[pos]=sum;
}
else if(len==c[pos]) d[pos]+=sum;
pos+=lowbit(pos);
}
} int query_len(int pos)
{
int ans=;
while(pos)
{
ans= ans>=c[pos] ? ans : c[pos];
pos-=lowbit(pos);
}
return ans;
} double query_sum(int pos,int val)
{
double ans=;
while(pos)
{
if(c[pos]==val) ans+=d[pos];
pos-=lowbit(pos);
}
return ans;
} void clear(int pos)
{
while(pos<=n)
{
c[pos]=d[pos]=;
pos+=lowbit(pos);
}
} void cdq(int l,int r)
{
if(l==r) return;
int mid=l+r>>;
cdq(l,mid);
sort(e+l,e+mid+,cmdy);
sort(e+mid+,e+r+,cmdy);
int i=l,j=mid+;
int len; double sum;
for(;j<=r;++j)
{
while(i<=mid && e[i].y<=e[j].y)
{
change(e[i].z,e[i].len,e[i].sum);
i++;
}
len=query_len(e[j].z)+;
sum=query_sum(e[j].z,len-);
if(len>e[j].len)
{
e[j].len=len;
e[j].sum=sum;
}
else if(len==e[j].len) e[j].sum+=sum;
}
for(int k=l;k<=mid;++k) clear(e[k].z);
sort(e+mid+,e+r+,cmdx);
cdq(mid+,r);
} void work()
{
sort(has+,has+n+);
tot=unique(has+,has+n+)-has-;
for(int i=;i<=n;++i) v[i]=lower_bound(has+,has+tot+,v[i])-has;
for(int i=;i<=n;++i)
{
e[i].x=i;
e[i].y=-h[i];
e[i].z=tot-v[i]+;
e[i].len=e[i].sum=;
}
cdq(,n);
for(int i=;i<=n;++i) pre_len[e[i].x]=e[i].len,pre_sum[e[i].x]=e[i].sum;
for(int i=;i<=n;++i)
{
e[i].x=-i;
e[i].y=h[i];
e[i].z=v[i];
e[i].len=e[i].sum=;
}
sort(e+,e+n+,cmdx);
cdq(,n);
for(int i=;i<=n;++i) suf_len[-e[i].x]=e[i].len,suf_sum[-e[i].x]=e[i].sum;
} void get_ans()
{
int mx=;
for(int i=;i<=n;++i) mx=max(mx,pre_len[i]);
printf("%d\n",mx);
double cnt=;
for(int i=;i<=n;++i)
if(pre_len[i]==mx) cnt+=pre_sum[i];
for(int i=;i<=n;++i)
if(pre_len[i]+suf_len[i]-==mx) printf("%.5lf ",(double)pre_sum[i]*suf_sum[i]/cnt);
else printf("0 ");
} int main()
{
read(n);
for(int i=;i<=n;++i)
{
read(h[i]); read(v[i]);
has[i]=v[i];
}
work();
get_ans();
}

bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹的更多相关文章

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

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

  2. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

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

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

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

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

  5. bzoj千题计划254:bzoj2286: [Sdoi2011]消耗战

    http://www.lydsy.com/JudgeOnline/problem.php?id=2286 虚树上树形DP #include<cmath> #include<cstdi ...

  6. bzoj千题计划246:bzoj2242: [SDOI2011]计算器

    http://www.lydsy.com/JudgeOnline/problem.php?id=2242 #include<map> #include<cmath> #incl ...

  7. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  8. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  9. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

随机推荐

  1. Dubbo+zookeeper搭建环境学习笔记

    Dubbo背景和简介 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 1.单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本 ...

  2. git 创建标签和删除标签

    创建标签 在Git中打标签非常简单,首先,切换到需要打标签的分支上: $ git branch * dev master $ git checkout master Switched to branc ...

  3. 阿里云ECS服务器源配置

    前段时间领取了阿里云ECS免费试用6个月的福利,此处记录一下服务器源配置过程和服务器用户创建过程. 一.CentOS源配置 1.备份 mv /etc/yum.repos.d/CentOS-Base.r ...

  4. 1065 A+B and C

    同样是一题会产生溢出的题,不同的是这个用大数类很麻烦,因为有负数的可能性 不妨利用溢出的特性来解题:两个整数和为负数 或者 两个负数和为正数,那么就溢出了. #include<bits/stdc ...

  5. DVWA渗透测试系列 一 (DVWA环境配置)

    DVWA介绍: DVWA是一个渗透测试靶机系统. DVWA具有十个模块:分别是 Brute Force(暴力破解).Command Injection(命令行注入).CSRF(跨站请求伪造).File ...

  6. Python进阶量化交易场外篇3——最大回撤评价策略风险

    新年伊始,很荣幸笔者的<教你用 Python 进阶量化交易>专栏在慕课专栏板块上线了,欢迎大家订阅!为了能够提供给大家更轻松的学习过程,笔者在专栏内容之外会陆续推出一些手记来辅助同学们学习 ...

  7. 浅介MVC与Backbone

    1.MVC是什么东西? MVC (Modal View Controler) 是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controll ...

  8. Test Cases

    对于mode1 1 路径下一个空文件夹       结果:生成一个空的txt 2路径下一个文件夹内包含一个txt内容为abd(最基本的一个单词) 3路径下一个空文件夹一个txt,txt内容为以不同符号 ...

  9. 小学四则运算APP 第一个冲刺阶段 第四天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第一次冲刺阶段时间:11.17~11.27 本次发布我们增加了CalculatorsActivity.java.YunsuanActivi ...

  10. PAT 1063 计算谱半径

    https://pintia.cn/problem-sets/994805260223102976/problems/994805267860930560 在数学中,矩阵的“谱半径”是指其特征值的模集 ...