【[SDOI2011]拦截导弹】
这道题是真的蛇皮
方案数要开\(double\)真的蛇皮
首先\(dp\)是非常容易看出来的
设\(dp[i]\)表示以\(i\)结尾的最长子序列
显然转移方程为
\]
暴力转移是\(O(n^2)\)的
同时第二问我们还需要求一个概率
非常简单,我们反正做一遍\(dp\),看看\(i\)之后能连接的最长子序列为多少
同时统计好两边的方案数,之后如果左右两边的长度拼起来等于最长的长度,那么就可以存在在答案里,于是概率就是\(\frac{\text{左边的方案数}\times\text{右边的方案数}}{\text{总方案数}}\)
之后核心就是求出方案数和子序列长度了
发现这就是一个三维偏序的问题,我们可以直接硬上\(CDQ\)分治
但是像板子里写的那样的\(CDQ\)是不行的,板子里的\(CDQ\)本质上后根遍历,所以用左边更新右边的时候\(dp\)数组并不能被更新全
于是略改一下板子,改成中根遍历,先处理左边,之后用左边的来更新右边的\(dp\)值,之后处理右边
这样就能够保证每一个位置被更新的时候其前面的位置都已经被更新了
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define re register
#define maxn 50005
#define lowbit(x) ((x)&(-x))
#define LL double
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
int H[maxn],HH[maxn];
int V[maxn],to[maxn];
int n,tot;
int lf[maxn],rf[maxn];
LL ld[maxn],rd[maxn];
inline int find(int x)
{
int l=1,r=tot;
while(l<=r)
{
int mid=l+r>>1;
if(H[mid]==x) return mid;
if(H[mid]>x) r=mid-1;
else l=mid+1;
}
return 0;
}
struct Node
{
int v,h,ans,rk;
LL d;
}a[maxn];
inline int cmp(Node A,Node B)
{
if(A.v==B.v) return A.h<B.h;
return A.v<B.v;
}
inline int cop(Node A,Node B)
{
return A.rk<B.rk;
}
int c[maxn];
LL bit[maxn];
inline void add(int x,int y,LL val)
{
for(re int i=x;i<=tot;i+=lowbit(i))
{
if(c[i]>y) continue;
if(c[i]==y) bit[i]+=val;
if(c[i]<y) c[i]=y,bit[i]=val;
}
}
inline int ask(int x) {int now=-1;for(re int i=x;i;i-=lowbit(i)) if(c[i]) now=max(now,c[i]);return now;}
inline LL query(int x,int M) {LL now=0;for(re int i=x;i;i-=lowbit(i)) if(c[i]&&c[i]==M) now+=bit[i];return now;}
inline void clear(int x) {for(re int i=x;i<=tot;i+=lowbit(i)) c[i]=0,bit[i]=0;}
void CDQ(int s,int t)
{
if(s==t) return;
int mid=s+t>>1;
CDQ(s,mid);
std::sort(a+s,a+mid+1,cmp),std::sort(a+mid+1,a+t+1,cmp);
int i=s,j=mid+1;
while(i<=mid&&j<=t)
{
if(a[i].v<=a[j].v) add(a[i].h,a[i].ans,a[i].d),i++;
else
{
int now=ask(a[j].h);
if(now!=-1)
{
if(now+1>a[j].ans) a[j].ans=now+1,a[j].d=query(a[j].h,now);
else if(now+1==a[j].ans) a[j].d+=query(a[j].h,now);
}
j++;
}
}
while(j<=t)
{
int now=ask(a[j].h);
if(now!=-1)
{
if(now+1>a[j].ans) a[j].ans=now+1,a[j].d=query(a[j].h,now);
else if(now+1==a[j].ans) a[j].d+=query(a[j].h,now);
}
j++;
}
for(re int k=s;k<i;k++) clear(a[k].h);
std::sort(a+mid+1,a+t+1,cop);
CDQ(mid+1,t);
}
int main()
{
n=read();
for(re int i=1;i<=n;i++) V[i]=-1*read(),H[i]=-1*read(),HH[i]=H[i],a[i].rk=i;
std::sort(H+1,H+n+1);
tot=std::unique(H+1,H+n+1)-H-1;
for(re int i=1;i<=n;i++)
to[i]=find(HH[i]);
for(re int i=1;i<=n;i++) a[i].v=V[i],a[i].h=to[i],a[i].ans=1,a[i].d=1;
CDQ(1,n);
int ans=0;LL now=0;
for(re int i=1;i<=n;i++) ans=max(ans,a[i].ans);
for(re int i=1;i<=n;i++) if(ans==a[i].ans) now+=a[i].d;
printf("%d\n",ans);
for(re int i=1;i<=n;i++) lf[a[i].rk]=a[i].ans,ld[a[i].rk]=a[i].d;
for(re int i=1;i<=n;i++)
V[i]=-1*V[i],HH[i]=-1*HH[i],H[i]=HH[i];
std::sort(H+1,H+n+1);
tot=std::unique(H+1,H+n+1)-H-1;
for(re int i=1;i<=n;i++)
to[i]=find(HH[i]);
for(re int i=n;i;--i) a[n-i+1].v=V[i],a[n-i+1].h=to[i],a[n-i+1].rk=n-i+1,a[n-i+1].ans=1,a[n-i+1].d=1;
CDQ(1,n);
for(re int i=1;i<=n;i++) a[i].rk=n-a[i].rk+1;
for(re int i=1;i<=n;i++) rf[a[i].rk]=a[i].ans,rd[a[i].rk]=a[i].d;
for(re int i=1;i<=n;i++)
{
if(rf[i]+lf[i]-1==ans)
printf("%.5lf ",rd[i]*ld[i]/now);
else printf("0.00000 ");
}
return 0;
}
【[SDOI2011]拦截导弹】的更多相关文章
- bzoj 2244: [SDOI2011]拦截导弹 cdq分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 237 Solved: ...
- 【BZOJ2244】[SDOI2011]拦截导弹(CDQ分治)
[BZOJ2244][SDOI2011]拦截导弹(CDQ分治) 题面 BZOJ 洛谷 题解 不难发现这就是一个三维偏序+\(LIS\)这样一个\(dp\). 那么第一问很好求,直接\(CDQ\)分治之 ...
- [BZOJ2244][SDOI2011]拦截导弹 CDQ分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MB Special Judge Description 某国为了防御敌国的导弹 ...
- 【LG2481】[SDOI2011]拦截导弹
[LG2481][SDOI2011]拦截导弹 题面 洛谷 题解 可以看出第一问就是一个有关偏序的\(LIS\),很显然可以用\(CDQ\)优化 关键在于第二问 概率\(P_i=\) \(总LIS数\) ...
- P2487 [SDOI2011]拦截导弹
题目 P2487 [SDOI2011]拦截导弹 做\(SDOI\)有种想评黑的感觉,果然还是太弱了 做法 独立写(调)代码三个小时祭 简化题目:求二维最长不上升子序列及每个点出现在最长不上升子序列概率 ...
- BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治
2244: [SDOI2011]拦截导弹 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截 ...
- BZOJ2244 [SDOI2011]拦截导弹 【cdq分治 + 树状数组】
题目 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高于前一发的高度,其 ...
- BZOJ2244: [SDOI2011]拦截导弹(CDQ分治,二维LIS,计数)
Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截任意速度的导弹,但是以后每一发炮弹都不能高 ...
- bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2244 [题意] 给定n个二元组,求出最长不上升子序列和各颗导弹被拦截的概率. [思路] ...
- bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹
http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...
随机推荐
- jenkins学习之centos6.9下安装
以下为centos6.9下测试安装: docker下安装jenkins: 更新yum源: yum -y update 安装docker: yum -y install docker-io 启动dock ...
- kinect 深度图像去噪算法
算法设计思路 (1)读取16位深度图像到待处理图像帧组: (2)ROI区域计算 由于kinect 彩色摄像头和红外深度摄像头是存在视角偏差的,经过视角对齐后,得到的深度图像是有黑边的.此处通过取帧组第 ...
- Java新人拿到一台新的电脑需要装配什么
适用对象:新手 装备:win10 一.IDEA 插件等 说明 其他 TranslationPlugin 翻译插件 GitHub地址 MyBatis-Generator 自动生成Mybatis文件 Al ...
- groovy对枚举的支持
/** * Created by Jxy on 2019/1/3 15:42 * groovy对枚举的支持 */ enum CoffeeSize{ SHORT,SMALL,BIG,MUG } def ...
- CODEFORCES 429B 动态规划
http://codeforces.com/problemset/problem/429/B 可以参考这篇文章: http://blog.csdn.net/pure_lady/article/deta ...
- RN canvas画布大小之谜
一.需求 在一个高640.宽360的canvas内画一些坐标点. 二.问题 坐标点只显示了一部分,剩下的点没显示(其坐标属于(640,360)区域). 三.原因 canvas默认的画布大小是高150, ...
- lnmp环境 开启pathinfo
thinkphp url访问模式中 默认的pathinfo不起作用? 1.检查你的tp配置文件config.php URL模式 'url_model'=> '1', //URL模式 即pathi ...
- Java设计模式—命令模式
命令模式是一个高内聚的模式. 定义如下:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 通用类图如下: 角色说明: ● Re ...
- 英文版win10更新以后, 中文软件变成乱码
原因是非Unicode程序的语言设置失效了 在区域设置里把当前系统区域设置改成"英语(美国)", 重启电脑后再改回"中文(简体, 中国)", 再重启就好了.
- SP从32位系统到64位系统的迁移方法
前提:目标系统为64位1.在32位系统下正常安装SP,获取SP运行时必须的文件2.将[浪潮集团金融事业部]目录拷贝到目标系统的[C:\Program Files]目录3.进入目标系统的[浪潮集团金融事 ...