传送门

题解

看了半天完全没发现这东西和CDQ有什么关系……

先把原序列翻转,求起来方便

然后把每一个位置表示成$(a,b,c)$其中$a$表示位置,$b$表示高度,$c$表示速度,求有多少个位置$a,b,c$都小于它,这就是一个三维偏序问题,直接CDQ就可以解决了……

然后考虑如何求第二问,就是一个导弹所在的LIS数/总的LIS数,因为一个导弹的LIS必须包含自己,以$g[i]$表示以$i$结尾的LIS总数,不难发现有如下转移式

$$g[i]=\sum g[j] \{ (i<j,h[i]<h[j],v[i]<v[j],f[j]+1=f[i]\}$$

这个也可以用CDQ来解决,只要统计出之前最大的LIS再和$f$比较就好了(完全没想出来怎么会这么神仙……)

然后再求出以$i$为开头的LIS长度和方案数,两个相乘就是他自己的方案数了

代码好长……调了好久……

 //minamoto
#include<bits/stdc++.h>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
struct BIT{
int f;double w;
BIT(){f=,w=;}
BIT(int f,double w):f(f),w(w){}
}c[N];
int n,st[N],top=;
inline void add(int x,int f,double w){
for(int i=x;i<=n;i+=i&-i){
if(c[i].f<f){
if(c[i].f==) st[++top]=i;
c[i]=(BIT){f,w};
}
else if(c[i].f==f) c[i].w+=w;
}
}
inline BIT query(int x){
BIT res;
for(int i=x;i;i-=i&-i){
if(c[i].f>res.f) res=c[i];
else if(c[i].f==res.f) res.w+=c[i].w;
}
return res;
}
struct node{
int h,v,id,t;
int f[];double g[];
}a[N],q[N];
int wh[N],wv[N],id[N],rk[N];
inline bool cmp(int i,int j)
{return a[i].h<a[j].h||(a[i].h==a[j].h&&a[i].id<a[j].id);}
inline bool cmpid(const node &a,const node &b)
{return a.id<b.id;}
void solve(int l,int r,int t){
if(l==r){
if(a[l].f[t]<) a[l].f[t]=a[l].g[t]=;
return;
}
int mid=(l+r)>>;
memcpy(q+l,a+l,sizeof(node)*(r-l+));
int q1=l,q2=mid+;
for(int i=l;i<=r;++i){
q[i].t<=mid?a[q1++]=q[i]:a[q2++]=q[i];
}
solve(l,mid,t);
q1=l;
for(int i=mid+;i<=r;++i){
while(q1<=mid&&a[q1].id<a[i].id) add(a[q1].v,a[q1].f[t],a[q1].g[t]),++q1;
BIT res=query(a[i].v);
if(res.f==) continue;
if(res.f+>a[i].f[t]){
a[i].f[t]=res.f+,a[i].g[t]=res.w;
}
else if(res.f+==a[i].f[t]) a[i].g[t]+=res.w;
}
while(top){c[st[top--]]=(BIT){,};}
solve(mid+,r,t);
merge(a+l,a+mid+,a+mid+,a+r+,q+l,cmpid);
memcpy(a+l,q+l,sizeof(node)*(r-l+));
}
int th=,tv=;
int main(){
//freopen("testdata.in","r",stdin);
n=read();
for(int i=;i<=n;++i){
wh[i]=a[i].h=read(),wv[i]=a[i].v=read(),a[i].id=i,rk[i]=i;
}
sort(wh+,wh++n),sort(wv+,wv++n);
th=unique(wh+,wh++n)-wh-,tv=unique(wv+,wv++n)-wv-;
for(int i=;i<=n;++i){
a[i].h=th-(lower_bound(wh+,wh+th+,a[i].h)-wh)+;
a[i].v=tv-(lower_bound(wv+,wv+tv+,a[i].v)-wv)+;
}
sort(rk+,rk++n,cmp);
for(int i=;i<=n;++i) a[rk[i]].t=i;
solve(,n,);
for(int i=;i<=n;++i){
a[i].h=th-a[i].h+;
a[i].v=tv-a[i].v+;
a[i].id=n-a[i].id+;
a[i].t=n-a[i].t+;
}
reverse(a+,a++n);
solve(,n,);
reverse(a+,a++n);
double sum=;int ans=;
for(int i=;i<=n;++i){
int len=a[i].f[]+a[i].f[]-;
cmax(ans,len);
}
printf("%d\n",ans);
for(int i=;i<=n;++i){
if(a[i].f[]==ans) sum+=a[i].g[]*a[i].g[];
}
for(int i=;i<=n;++i){
double res=a[i].g[]*a[i].g[];
printf("%.5lf ",(a[i].f[]+a[i].f[]-==ans)?(res/sum):);
}
return ;
}

bzoj 2244 [SDOI2011]拦截导弹(dp+CDQ+树状数组)的更多相关文章

  1. BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治

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

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

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

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

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

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

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

  5. BZOJ 1176/2683 Mokia (三维偏序CDQ+树状数组)

    题目大意: 洛谷传送门 三维偏序裸题.. 每次操作都看成一个三元组$<x,y,t>$,表示$x,y$坐标和操作时间$t $ 询问操作拆成$4$个容斥 接下来就是$CDQ$了,外层按t排序, ...

  6. bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2244 [题意] 给定n个二元组,求出最长不上升子序列和各颗导弹被拦截的概率. [思路] ...

  7. BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)

    题目大意: 洛谷传送门 不愧为SDOI的duliu题 第一问?二元组的最长不上升子序列长度?裸的三维偏序问题,直接上$CDQ$ 由于是不上升,需要查询某一范围的最大值,并不是前缀最大值,建议用线段树实 ...

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

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

  9. bzoj 2244: [SDOI2011]拦截导弹

    #include<cstdio> #include<iostream> #include<algorithm> #define M 100009 using nam ...

随机推荐

  1. Symfony 建立一个Bundle

    如果说,这个时候你萌生了一个去看一看Symfony源码的想法,个人建议还是算了,看了之后,你就会感到非常迷茫.因为他实在是大于绝大部分你使用过的框架,并且有多达近二十个的插件,使用了一些非常精巧的设计 ...

  2. Api2Doc生成 Restful API 文档

    1,引入maven <dependency> <groupId>com.github.terran4j</groupId> <artifactId>te ...

  3. CLR如何控制类型中的字段排序

    [StructLayout(LayoutKind.Sequential) ]保持字段布局 [StructLayout(LayoutKind.Auto) ]CLR自动选择最优 [StructLayout ...

  4. Cocoa Touch(六):App运行机制 NSRunLoop, KVC, KVO, Notification, ARC

    事件循环NSRunLoop 1.run loop概念 NSRunLoop类封装了线程进入事件循环的过程,一个runloop实例就表示了一个线程的事件循环.更具体的说,在iOS开发框架中,线程每次执行完 ...

  5. mybatis调用自定义函数

    <select id="getFunction" parameterType="int" resultType="string"> ...

  6. JavaScript 分号使用总结

    没有应该不应该,只有你自己喜欢不喜欢.JavaScript 语法长得 C-like 不代表它本质上和 C 是一类语言,所有直觉性的 "当然应该加分号" 都是保守的.未经深入思考的草 ...

  7. open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory 解决方案

    方法一.  yum安装 yum install *rhsm* 方法二 (我是用这方法解决的) 执行命令: ①   wget http://mirror.centos.org/centos/7/os/x ...

  8. Golang使用pkg-config自动获取头文件和链接库的方法

    为了能够重用已有的C语言库,我们在使用Golang开发项目或系统的时候难免会遇到Go和C语言混合编程,这时很多人都会选择使用cgo. 话说cgo这个东西可算得上是让人又爱又恨,好处在于它可以让你快速重 ...

  9. 五)Spring + Quartz 复杂业务的两个问题:获取Spring上下文 和 自动注入服务类

    配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...

  10. Altera FPGA 开启引脚片上上拉电阻功能

    本博文以矩阵键盘实验为例,介绍了如何开启FPGA管脚的片上上拉电阻. Cyclone IV E FPGA的通用输入输出管脚都支持内部弱上拉电阻,但是时钟输入脚不支持.所以,当需要上拉电阻的信号(如本例 ...