题目大意:

洛谷传送门

不愧为SDOI的duliu题

第一问?二元组的最长不上升子序列长度?裸的三维偏序问题,直接上$CDQ$

由于是不上升,需要查询某一范围的最大值,并不是前缀最大值,建议用线段树实现

第二问是个什么玩意??

画画图发现需要正反各做一次$CDQ$来统计

如果某个位置正反的答案$-1$就是最长长度

那么它被选择的次数就是 正着统计作为末尾的次数*反着统计作为末尾的次数

概率就是这个值/总次数

又发现某个位置作为末尾的次数可能非常非常大!

比如$1\;1\;2\;2\;3\;3\;4\;4\;5\;5....$这个值甚至达到了$2^{n/2}$

而题目又是让我们求概率,所以这个次数必须要用$double$存

蒟蒻的代码写得比较恶心..

另外听一些神犇说$sort$中的$cmp$里不能写$<=$或$>=$,不然会$RE$

 #include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 50100
#define ll long long
#define dd double
#define inf 0x3f3f3f3f3f3f3f3fll
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,mh,mv,K;
inline void chk(int &ma,dd &sum,int w,dd num)
{
if(w>ma) ma=w,sum=num;
else if(w==ma) sum+=num;
} struct SEG{
int ma[N1<<]; dd sum[N1<<];
void pushup(int rt)
{
ma[rt]=; sum[rt]=;
chk(ma[rt],sum[rt],ma[rt<<],sum[rt<<]);
chk(ma[rt],sum[rt],ma[rt<<|],sum[rt<<|]);
}
void update(int x,int l,int r,int rt,int w,dd num)
{
if(l==r) { chk(ma[rt],sum[rt],w,num); return; }
int mid=(l+r)>>;
if(x<=mid) update(x,l,mid,rt<<,w,num);
else update(x,mid+,r,rt<<|,w,num);
pushup(rt);
}
void query(int L,int R,int l,int r,int rt,int &w,dd &num)
{
if(L<=l&&r<=R) { chk(w,num,ma[rt],sum[rt]); return; }
int mid=(l+r)>>;
if(L<=mid) query(L,R,l,mid,rt<<,w,num);
if(R>mid) query(L,R,mid+,r,rt<<|,w,num);
}
void clr(int x,int l,int r,int rt)
{
ma[rt]=; sum[rt]=;
if(l==r) return; int mid=(l+r)>>;
if(x<=mid) clr(x,l,mid,rt<<);
else clr(x,mid+,r,rt<<|);
}
}s;
struct node{int h,v,t,ans; dd sum;}a[N1],c[N1],tmp[N1];
int h[N1],v[N1],que[N1],tl; int cmp1(node s1,node s2){ if(s1.h!=s2.h) return s1.h>s2.h; return s1.v>=s2.v; }
int cmp2(node s1,node s2){ if(s1.h!=s2.h) return s1.h<s2.h; return s1.v<=s2.v; }
int cmpp(node s1,node s2){ if(s1.h!=s2.h) return s1.h>s2.h; return s1.v>s2.v; }
int cmpn(node s1,node s2){ if(s1.h!=s2.h) return s1.h<s2.h; return s1.v<s2.v; } void CDQ1(int L,int R)
{
if(R-L<=) return;
int M=(L+R)>>,i,j,k,cnt;
for(i=L,j=M,k=L;k<R;k++)
{
if(a[k].t<M) tmp[i++]=a[k];
else tmp[j++]=a[k];
}
for(k=L;k<R;k++) a[k]=tmp[k];
CDQ1(L,M);
for(i=L,j=M;i<M&&j<R;)
{
if(cmp1(a[i],a[j])) { s.update(a[i].v,,mv,,a[i].ans+,a[i].sum); que[++tl]=i; i++; }
else { s.query(a[j].v,mv,,mv,,a[j].ans,a[j].sum); j++; }
}
while(j<R) { s.query(a[j].v,mv,,mv,,a[j].ans,a[j].sum); j++;}
while(tl) { s.clr(a[que[tl--]].v,,mv,); }
CDQ1(M,R);
for(i=L,j=M,cnt=;i<M&&j<R;)
{
if(cmp1(a[i],a[j])) { tmp[++cnt]=a[i]; i++; }
else { tmp[++cnt]=a[j]; j++;}
}
while(i<M) tmp[++cnt]=a[i++];
while(j<R) tmp[++cnt]=a[j++];
for(k=L;k<R;k++) a[k]=tmp[k-L+];
}
void CDQ2(int L,int R)
{
if(R-L<=) return;
int M=(L+R)>>,i,j,k,cnt;
for(i=L,j=M,k=L;k<R;k++)
{
if(a[k].t<M) tmp[i++]=a[k];
else tmp[j++]=a[k];
}
for(k=L;k<R;k++) a[k]=tmp[k];
CDQ2(L,M);
for(i=L,j=M;i<M&&j<R;)
{
if(cmp2(a[i],a[j])) { s.update(a[i].v,,mv,,a[i].ans+,a[i].sum); que[++tl]=i; i++; }
else { s.query(,a[j].v,,mv,,a[j].ans,a[j].sum); j++; }
}
while(j<R) { s.query(,a[j].v,,mv,,a[j].ans,a[j].sum); j++;}
while(tl) { s.clr(a[que[tl--]].v,,mv,); }
CDQ2(M,R);
for(i=L,j=M,cnt=;i<M&&j<R;)
{
if(cmp2(a[i],a[j])) { tmp[++cnt]=a[i]; i++; }
else { tmp[++cnt]=a[j]; j++;}
}
while(i<M) tmp[++cnt]=a[i++];
while(j<R) tmp[++cnt]=a[j++];
for(k=L;k<R;k++) a[k]=tmp[k-L+];
}
dd ret[N1];
int p[N1];
int de; int main()
{
scanf("%d",&n);
int i,j,x,y,ans=; dd sum=;
for(i=;i<=n;i++) { h[i]=a[i].h=gint(); v[i]=a[i].v=gint(); a[i].t=i; a[i].ans=; a[i].sum=; }
sort(h+,h+n+); mh=unique(h+,h+n+)-(h+); sort(v+,v+n+); mv=unique(v+,v+n+)-(v+);
for(i=;i<=n;i++) { a[i].h=lower_bound(h+,h+mh+,a[i].h)-h; a[i].v=lower_bound(v+,v+mv+,a[i].v)-v;}
sort(a+,a+n+,cmpp);
CDQ1(,n+);
for(i=;i<=n;i++) { c[i]=a[i]; p[a[i].t]=i; chk(ans,sum,a[i].ans,a[i].sum); }
sort(a+,a+n+,cmpn); for(i=;i<=n;i++) { a[i].ans=; a[i].sum=; a[i].t=n-a[i].t+; }
CDQ2(,n+);
for(i=;i<=n;i++)
{
j=p[n-a[i].t+];
if(a[i].ans+c[j].ans-<ans) ret[c[j].t]=;
else ret[c[j].t]=1.0*c[j].sum*a[i].sum/sum;
}
printf("%d\n",ans);
for(i=;i<=n;i++) printf("%.5lf ",ret[i]);
puts(""); return ;
}

BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    问题: printf("%.5f ",0):为什么错了? 注意: 初始值很重要 题解: 三维偏序问题: 记录从前往后最长上升子序列长度pref,条数preg 从后往前suff,su ...

随机推荐

  1. P1546 最短网络 Agri-Net (kruskal)

    题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 题目描述 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其 ...

  2. Flask-SQLAlchemy中解决数据库连接1366报错

    报错信息:Warning: (1366, "Incorrect string value: '\\xD6\\xD0\\xB9\\xFA\\xB1\\xEA...' for column 'V ...

  3. struct 模块解决 TCP黏包问题

    首先来看一下产生黏包现象的一段代码: # server.py 服务端 import socket ​ sk = socket.socket() sk.bind(('127.0.0.1',9000)) ...

  4. 02018_StringBuffer练习

    1.已知int[] arr = {34,12,89,68}; 将其中的元素转成字符串,格式 [34,12,89,68]: 参考:02011_定义打印数组元素方法,按照给定的格式打印[11, 33, 4 ...

  5. query ajax总是进入error回调函数

    query ajax总是进入error回调函数今天纠结了1小时,ajax总是进入了error函数中.平时使用从来没有出现过这种现象,纠结了半小时. 最后稍微总结出了点: 1.以前使用都是服务器端输出S ...

  6. 绘图-CAD-改快捷键

    CAD的快捷键应该在左手边,左手不离开键盘,右手不离开鼠标,这样的操作才有效率. arc 圆弧命令原命令是ARC Q 圆(CIRCLE) C 原快捷键C被定义为COPY,Q的形状类似圆,只是多了一个尾 ...

  7. Linux-经常用到的几个命令

    -- |" 拷贝本地到远程 scp /serverdata/server/tomcat-uaac/webapps/dm.war root@172.16.7.123:/serverdata/s ...

  8. Java推断文本文件编码格式以及读取

    假设不是约定好的,要想解析txt文件就须要知道文件编码类型,因为文件编码类型众多.比如UTF-8,GBK.UTF-16,GB2312等等. 事实上有简单的办法.仅仅须要这样就能够了 String fi ...

  9. 关于App class loader的总结

    关于App class loader的总结 2010-05-11 15:19:09 分类: 系统运维 Java本身是一种设计的非常简单,非常精巧的语言,所以Java背后的原理也很简单,归结起来就是两点 ...

  10. Android 零基础学习之路

    第一阶段:Java面向对象编程 1.Java基本数据类型与表达式,分支循环. 2.String和StringBuffer的使用.正則表達式. 3.面向对象的抽象.封装,继承,多态.类与对象.对象初始化 ...