【题目链接】

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

【题意】

给定n个二元组,求出最长不上升子序列和各颗导弹被拦截的概率。

【思路】

DP+CDQ分治+BIT

先把序列反转一下,lis求起来方便。

对于第一问,我们要求的是

f[i]=max{ f[j] },j<i,x[j]<x[i],y[j]<y[i]

发现需要满足的条件就是一个三维偏序,可以用CDQ分治求解

不难发现第二问其实就等于:一颗导弹所在的lis数/总的lis数。一个导弹所在的lis必须包含自己,所以我们设g[i]表示以i为结尾的lis总数,则有转移式:

g[i]=sigma{ g[j] }, j<i,x[j]<x[i],y[j]<y[i],f[j]+1=f[i]

依旧可以用CDQ分治求。注意到最后的一个f的关系,这时候只需要统计出之前的最大lis值再与f相比较就可以了(蒟蒻的我一直苦思冥想。。。

相似的可以求出g’f’。都是g f的相反定义,即以i开头的…

奇技淫巧:我们可以在反转一下并对序列取一下反,这样就都可以套用函数辣。貌似离散化之后跑得飞快,一跃直上rk3

【代码】

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=b;a<=c;a++)
using namespace std; const int N = 1e5+; struct Node {
int id,x,y;
bool operator<(const Node& rhs)const {
return x<rhs.x||(x==rhs.x&&y<rhs.y);
}
}q[N],t[N];
bool cmp(const Node& a,const Node& b)
{
return a.id<b.id;
} int f[][N]; double g[][N],ans[N];
int hash[N],tot,n; int read()
{
char c=getchar(); int x=; int f=;
while(!isdigit(c)){if(c=='-')f=-; c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
return x*f;
} int t_f[N],tag[N],T; double t_g[N];
void add(int x,int f,double g)
{
for(;x<=tot;x+=x&-x) {
if(tag[x]!=T) {tag[x]=T;t_f[x]=;t_g[x]=;}
if(f>t_f[x]){t_f[x]=f;t_g[x]=g;}
else if(f==t_f[x]) t_g[x]+=g;
}
}
void query(int x,int& mx,double& sum)
{
mx=; sum=0.0;
for(;x;x-=x&-x) if(tag[x]==T){
if(t_f[x]>mx) {
mx=t_f[x]; sum=t_g[x];
} else if(t_f[x]==mx)
sum+=t_g[x];
}
} void solve(int l,int r,int ty)
{
if(l==r) {
if(!f[ty][l]){
f[ty][l]=; g[ty][l]=;
}
return ;
}
int mid=(l+r)>>;
int l1=l,l2=mid+,i,j,cnt=;
for(i=l;i<=r;i++) {
if(q[i].id<=mid) t[l1++]=q[i];
else t[l2++]=q[i];
}
memcpy(q+l,t+l,sizeof(Node)*(r-l+));
solve(l,mid,ty);
T++;
sort(q+mid+,q+r+);
for(i=mid+,j=l;i<=r;i++)
{
int id;
for(;j<=mid&&q[j].x<=q[i].x;j++) {
id=q[j].id; cnt++;
add(q[j].y,f[ty][id],g[ty][id]);
}
int mx; double sum;
query(q[i].y,mx,sum);
id=q[i].id;
if(mx>) {
if(mx+>f[ty][id]) {
f[ty][id]=mx+; g[ty][id]=sum;
} else if(mx+==f[ty][id]) {
g[ty][id]+=sum;
}
}
}
solve(mid+,r,ty);
l1=l,l2=mid+; int now=l;
while(l1<=mid||l2<=r) {
if(l2>r||l1<=mid&&q[l1]<q[l2]) t[now++]=q[l1++];
else t[now++]=q[l2++];
}
memcpy(q+l,t+l,sizeof(Node)*(r-l+));
} int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
n=read();
int mxx=;
FOR(i,,n)
{
q[i].x=read(),q[i].y=read();
hash[i]=q[i].y;
mxx=max(mxx,q[i].x);
}
sort(hash+,hash+n+);
tot=unique(hash+,hash+n+)-hash-;
FOR(i,,n)
q[i].y=lower_bound(hash+,hash+tot+,q[i].y)-hash;
reverse(q+,q+n+);
FOR(i,,n) q[i].id=i;
solve(,n,); sort(q+,q+n+,cmp);
reverse(q+,q+n+);
FOR(i,,n)
q[i].x=mxx-q[i].x+,q[i].y=tot-q[i].y+,
q[i].id=i;
solve(,n,);
int mx=; double sum=;
FOR(i,,n) {
int tmp=f[][i];
if(tmp>mx) {
mx=tmp; sum=g[][i]*g[][n-i+];
} else if(tmp==mx)
sum+=g[][i]*g[][n-i+];
}
printf("%d\n",mx);
for(int i=n;i;i--) {
if(f[][i]+f[][n-i+]-==mx) {
ans[i]=(g[][i]*g[][n-i+])/sum;
} else ans[i]=;
}
for(int i=n;i>;i--) printf("%.5lf ",ans[i]);
printf("%.5lf",ans[]);
return ;
}

bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)的更多相关文章

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

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

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

    [BZOJ2244][SDOI2011]拦截导弹(CDQ分治) 题面 BZOJ 洛谷 题解 不难发现这就是一个三维偏序+\(LIS\)这样一个\(dp\). 那么第一问很好求,直接\(CDQ\)分治之 ...

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

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

  4. BZOJ - 2244 拦截导弹 (dp,CDQ分治+树状数组优化)

    题目链接 dp进阶之CDQ分治优化dp. 前置技能:dp基本功底,CDQ分治,树状数组. 问题等价于求二维最长上升子序列,是一个三维偏序问题(时间也算一维). 设$dp[i]=(l,x)$为以第i枚导 ...

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

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

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

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

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

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

  8. bzoj 2244 [SDOI2011]拦截导弹(dp+CDQ+树状数组)

    传送门 题解 看了半天完全没发现这东西和CDQ有什么关系…… 先把原序列翻转,求起来方便 然后把每一个位置表示成$(a,b,c)$其中$a$表示位置,$b$表示高度,$c$表示速度,求有多少个位置$a ...

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

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

随机推荐

  1. unity 3d 获取鼠标当前坐标

    获取当前鼠标position:Input.mousePosition;

  2. oracle中int类型和number类型区别

    INT类型是NUMBER类型的子类型.下面简要说明:(1)NUMBER(P,S)该数据类型用于定义数字类型的数据,其中P表示数字的总位数(最大字节个数),而S则表示小数点后面的位数.假设定义SAL列为 ...

  3. Spark的TorrentBroadcast:实现

    依据Spark 1.4版 序列化和反序列化 前边提到,TorrentBroadcast的关键就在于特殊的序列化和反序列化设置.1.1版的TorrentBroadcast实现了自己的readObject ...

  4. WPF性能优化经验总结

    WPF性能优化一.Rendering Tier 1. 根据硬件配置的不同,WPF采用不同的Rendering Tier做渲染.下列情况请特别注意,因为在这些情况下,即使是处于Rendering Tie ...

  5. jmeter HTTP信息头管理器使用一例

    最近在测试过程中遇到一个问题,被测系统会检测http header:如果不包含制定内容会引发302跳转操作,从而是测试达不到效果.解决办法,增加http 信息头管理器,直接上图 此处注意: 1.此处“ ...

  6. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  7. MVC @Html.DropDownListFor 默认值

    今天在做MVC 的 @Html.DropDownListFor  的时候,本来数据库中读取到的值是HK,但是 @Html.DropDownListFor的起始默认值始终是“请选择国家”,搞了一个下午, ...

  8. 删除appcompat_v7会出很多错误

    创建工程的时候会出现appcompat_v7这个文件夹 手贱删除后,发现出错了 说明test项目是依赖于appcompat_v7包的,所以这个appcompat_v7包是不能被删除的. appcomp ...

  9. UVA548——Tree(中后序建树+DFS)

    Tree You are to determine the value of the leaf node in a given binary tree that is the terminal nod ...

  10. uva 11292 Dragon of Loowater (勇者斗恶龙)

    Problem C: The Dragon of Loowater Once upon a time, in the Kingdom of Loowater, a minor nuisance tur ...