BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)
题意
略…
分析
就是求最长不上升子序列,坐标取一下反就是求最长不下降子序列,比较大小是二维(h,v)(h,v)(h,v)的比较.我们不看概率,先看第一问怎么求最长不降子序列.设f[i]f[i]f[i]表示以iii结尾的最长不降子序列的长度,有f[i]=max(f[j]+1) ( 0≤j<i,hj≤hi,vj≤vi )f[i]=max(f[j]+1)\ (\ 0\le j<i,h_j\le h_i,v_j\le v_i\ )f[i]=max(f[j]+1) ( 0≤j<i,hj≤hi,vj≤vi )那这就是一个三维偏序问题,只需要第一维CDQCDQCDQ,第二维排序,第三维用树状数组维护就行了.
要求概率,再定义g[i]g[i]g[i]表示以iii开始的最长不降子序列的长度.要求g[i]g[i]g[i]就坐标取反从nnn到111再做一次DPDPDP就行了.我们再设[0][0][0]表示序列长度,[1][1][1]表示这个长度的序列的方案.那对于iii点在最长不降子序列上的概率就是 f[i][1]∗g[i][1] ( f[i][0]+g[i][0]−1=LIS )∑1≤j≤nf[j][1] ( f[j][0]=LIS )\frac{f[i][1]*g[i][1]\ (\ f[i][0]+g[i][0]-1=LIS\ )}{\sum_{1\le j\le n} f[j][1]\ (\ f[j][0]=LIS\ )}∑1≤j≤nf[j][1] ( f[j][0]=LIS )f[i][1]∗g[i][1] ( f[i][0]+g[i][0]−1=LIS )分母其实就是总的最长上升子序列数量.
时间复杂度O(nlog2n)O(nlog^2n)O(nlog2n)
第一次写这样的CDQCDQCDQ,感觉好强…(是我太菜)
CODE
其实CDQCDQCDQ分治和树状数组都要离散化,但是标号本来就是1...n1...n1...n,就只用离散化vvv了.
代码还是蛮短的
#include <cctype>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char cb[1<<15],*cs=cb,*ct=cb;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
template<class T>inline void read(T &res) {
char ch; int flg = 1; for(;!isdigit(ch=getchar());)if(ch=='-')flg=-flg;
for(res=ch-'0';isdigit(ch=getchar());res=res*10+ch-'0'); res*=flg;
}
const int MAXN = 50005;
int n, bin[MAXN], tot, indx, stk[MAXN];
struct node { //写一个结构体
int x; double y; //方案数要用double不然会溢出
node() { x = y = 0; }
node(int _x, double _y):x(_x), y(_y){}
inline bool operator <(const node &o)const { return x < o.x; }
}T[MAXN];
inline void chkmax(node &A, const node &B) {
if(B < A) return;
if(A < B) A = B;
else A.y += B.y;
}
inline void upd(int x, node val) {
while(x <= tot) {
if(val.x > T[x].x) {
if(!T[x].x) stk[++indx] = x; //第一次修改就进栈
T[x] = val;
}
else if(val.x == T[x].x) T[x].y += val.y;
x += x&-x;
}
}
inline node qsum(int x) {
node res;
while(x) chkmax(res, T[x]), x -= x&-x;
return res;
}
struct Node { int i, h, v; node f; };
inline bool cmp2(const Node &A, const Node &B) { return A.h == B.h ? A.i < B.i : A.h < B.h; }
inline bool cmp(const Node &A, const Node &B) { return A.i < B.i; }
struct CDQ {
Node a[MAXN], tmp[MAXN];
void cdq(int l, int r) {
if(l == r) { if(!a[l].f.x || !a[l].f.y) a[l].f.x = a[l].f.y = 1; return; }
int mid = (l + r) >> 1;
int L = l, R = mid+1;
for(int i = l; i <= r; ++i) //分成左右两边
if(a[i].i <= mid) tmp[L++] = a[i];
else tmp[R++] = a[i];
for(int i = l; i <= r; ++i) a[i] = tmp[i];
cdq(l, mid);
sort(a + l, a + mid + 1, cmp2); L = l;
for(int i = mid+1; i <= r; ++i) {
while(L <= mid && a[i].h >= a[L].h) upd(a[L].v, a[L].f), ++L;
node res = qsum(a[i].v);
if(!res.x) continue;
++res.x, chkmax(a[i].f, res);
}
while(indx) T[stk[indx--]] = node(0, 0); //清零树状数组
cdq(mid+1, r);
}
}dp[2];
int main () {
read(n);
for(int i = 1; i <= n; ++i) {
dp[0].a[i].i = i, read(dp[0].a[i].h), read(dp[0].a[i].v);
dp[0].a[i].h *= -1, dp[0].a[i].v *= -1;
bin[++tot] = dp[0].a[i].v;
}
sort(bin + 1, bin + tot + 1); //只离散化V
tot = unique(bin + 1, bin + tot + 1) - bin - 1;
for(int i = 1; i <= n; ++i) {
dp[0].a[i].v = lower_bound(bin + 1, bin + tot + 1, dp[0].a[i].v) - bin;
dp[1].a[n-i+1].i = n-i+1;
dp[1].a[n-i+1].h = -dp[0].a[i].h;
dp[1].a[n-i+1].v = tot-dp[0].a[i].v+1;
}
sort(dp[0].a + 1, dp[0].a + n + 1, cmp2), dp[0].cdq(1, n);
sort(dp[1].a + 1, dp[1].a + n + 1, cmp2), dp[1].cdq(1, n); //做两次
sort(dp[0].a + 1, dp[0].a + n + 1, cmp);
sort(dp[1].a + 1, dp[1].a + n + 1, cmp); //重排序为 1~n
node Ans;
for(int i = 1; i <= n; ++i)
chkmax(Ans, dp[0].a[i].f);
printf("%d\n", Ans.x);
for(int i = 1; i <= n; ++i)
if(dp[0].a[i].f.x + dp[1].a[n-i+1].f.x - 1 < Ans.x) printf("%.6f ", 0.0);
else printf("%.6f ", dp[0].a[i].f.y*dp[1].a[n-i+1].f.y/Ans.y);
return 0;
}
BZOJ 2244: [SDOI2011]拦截导弹 (CDQ分治 三维偏序 DP)的更多相关文章
- bzoj 2244: [SDOI2011]拦截导弹 cdq分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 237 Solved: ...
- BZOJ 2244 [SDOI2011]拦截导弹 ——CDQ分治
三维偏序,直接CDQ硬上. 正反两次CDQ统计结尾的方案数,最后统计即可. #include <cstdio> #include <cstring> #include < ...
- BZOJ 2244: [SDOI2011]拦截导弹 [CDQ分治 树状数组]
传送门 题意:三维最长不上升子序列以及每个元素出现在最长不上升子序列的概率 $1A$了好开心 首先需要从左右各求一遍,长度就是$F[0][i]+F[1][i]-1$,次数就是$G[0][i]*G[1] ...
- BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治
2244: [SDOI2011]拦截导弹 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度.并且能够拦截 ...
- [BZOJ2244][SDOI2011]拦截导弹 CDQ分治
2244: [SDOI2011]拦截导弹 Time Limit: 30 Sec Memory Limit: 512 MB Special Judge Description 某国为了防御敌国的导弹 ...
- bzoj 2244 [SDOI2011]拦截导弹(DP+CDQ分治+BIT)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2244 [题意] 给定n个二元组,求出最长不上升子序列和各颗导弹被拦截的概率. [思路] ...
- BZOJ 2244 [SDOI2011]拦截导弹 (三维偏序CDQ+线段树)
题目大意: 洛谷传送门 不愧为SDOI的duliu题 第一问?二元组的最长不上升子序列长度?裸的三维偏序问题,直接上$CDQ$ 由于是不上升,需要查询某一范围的最大值,并不是前缀最大值,建议用线段树实 ...
- bzoj 2244 [SDOI2011]拦截导弹(dp+CDQ+树状数组)
传送门 题解 看了半天完全没发现这东西和CDQ有什么关系…… 先把原序列翻转,求起来方便 然后把每一个位置表示成$(a,b,c)$其中$a$表示位置,$b$表示高度,$c$表示速度,求有多少个位置$a ...
- bzoj 2244: [SDOI2011]拦截导弹
#include<cstdio> #include<iostream> #include<algorithm> #define M 100009 using nam ...
随机推荐
- 浪潮服务器NF84260M3安装Windows server 2012 R2 RAID配置
这里是已经做了RAID6,再做系统 浪潮服务器NF84260M3 U盘启动,光盘刻录 Windows server 2012 R2 镜像,地址:迅雷下载,ed2k://|file|cn_windows ...
- axios对请求各种异常情况处理的封装
前端网络请求封装 前端采用了axios来处理网络请求,为了避免在每次请求时都去判断各种各样的网络情况,比如连接超时.服务器内部错误.权限不足等等不一而足,我对axios进行了简单的封装,这里主要使用了 ...
- 为什么fastjson字段为null时不输出空字符串?
为什么fastjson字段为null时不输出空字符串? Map < String , Object > jsonMap = new HashMap< String , Object& ...
- (七)RequestMapping 和 Controller方法
文章目录 @[toc] RequestMapping功能 controller 方法返回值 RequestMapping功能 url映射 在定义 Controller 的,我们在方法上面,使用 @Re ...
- PostgreSQL练习3
select dname,count(ename),avg(sal),sum(sal) from emp e,dept d where e.deptno=d.deptno group by dname ...
- PB事件/函数的触发机制和触发方式
PB作为windows下的一个非常便捷的DB开发工具,有着和windows一样的消息触发机制PB提供了相应event/function触发机制和触发方式,用户可以根据自己的实际需要选用不同方法. 1. ...
- ThreadLocal使用场景,原理
ThreadLocal 1. 先说下 ThreadLocal不能解决多线程间共享数据,他是一个隔离多线程间共享数据的好帮手 2. ThreadLocal是本地线程共享数据 3. 他是以空间换时间 sy ...
- X86驱动:挂接SSDT内核钩子
SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用 ...
- echarts 根据经纬度坐标在地图上描点
var mapData = [ {'latitude':30.67, 'longitude':104.07}, {'latitude':34.76, 'longitude':113.65}, {'la ...
- 关于RESTful API
添几篇文章: 一.What Is REST? 二.RESTful API最佳实践 三.MS Azure——API Design 这些文章里面也推荐了一些关联文章,微软那篇最详细,非常值得一读.