【LG2481】[SDOI2011]拦截导弹
【LG2481】[SDOI2011]拦截导弹
题面
题解
可以看出第一问就是一个有关偏序的\(LIS\),很显然可以用\(CDQ\)优化
关键在于第二问
概率\(P_i=\) \(总LIS数\) / \(经过i的LIS数\)
分别正反跑两遍\(CDQ\)可以统计出分别以\(i\)为终点和起点的\(LIS\)数
乘起来就是经过\(i\)的方案数
比较坑的一点是\(long\) \(long\)存不下,要用\(double\)
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
namespace IO {
const int BUFSIZE = 1 << 20;
char ibuf[BUFSIZE], *is = ibuf, *it = ibuf;
inline char gc() {
if (is == it) it = (is = ibuf) + fread(ibuf, 1, BUFSIZE, stdin);
return *is++;
}
}
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (ch != '-' && (ch > '9' || ch < '0')) ch = IO::gc();
if (ch == '-') w = -1 , ch = IO::gc();
while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = IO::gc();
return w * data;
}
const int MAX_N = 50005;
struct Node {int h, v, i; } t[MAX_N]; int N;
bool cmp_h(const Node &a, const Node &b) { return a.h > b.h; }
bool cmp_v(const Node &a, const Node &b) { return a.v > b.v; }
bool cmp_i(const Node &a, const Node &b) { return a.i < b.i; }
inline int lb(int x) { return x & -x; }
int c[MAX_N]; double w[MAX_N];
void add(int x, int v, double W) {
while (x <= N) {
if (v == c[x]) w[x] += W;
else if (v > c[x]) c[x] = v, w[x] = W;
x += lb(x);
}
}
int sum(int x) {
int res = 0;
while (x > 0) res = max(res, c[x]), x -= lb(x);
return res;
}
double sum(int x, int v) {
double res = 0;
while (x > 0) res += (c[x] == v) ? w[x] : 0, x -= lb(x);
return res;
}
void Set(int x) { while (x <= N) c[x] = w[x] = 0, x += lb(x); }
int f[2][MAX_N]; double g[2][MAX_N];
void Div(int l, int r, int type) {
if (l == r) return ;
sort(&t[l], &t[r + 1], cmp_i);
if (type) reverse(&t[l], &t[r + 1]);
int mid = (l + r) >> 1;
Div(l, mid, type);
sort(&t[l], &t[mid + 1], cmp_h);
sort(&t[mid + 1], &t[r + 1], cmp_h);
int j = l;
for (int i = mid + 1; i <= r; i++) {
while (j <= mid && t[j].h >= t[i].h)
add(N + 1 - t[j].v, f[type][t[j].i], g[type][t[j].i]), ++j;
int res = sum(N + 1 - t[i].v) + 1;
if (res > f[type][t[i].i])
f[type][t[i].i] = res, g[type][t[i].i] = sum(N + 1 - t[i].v, res - 1);
else if (res == f[type][t[i].i]) g[type][t[i].i] += sum(N + 1 - t[i].v, res - 1);
}
for (int i = l; i <= mid; i++) Set(N + 1 - t[i].v);
Div(mid + 1, r, type);
}
int Sh[MAX_N], toth, Sv[MAX_N], totv;
int main () {
N = gi();
for (int i = 1; i <= N; i++) t[i] = (Node){gi(), gi(), i};
for (int i = 1; i <= N; i++) Sh[++toth] = t[i].h;
sort(&Sh[1], &Sh[toth + 1]); toth = unique(&Sh[1], &Sh[toth + 1]) - Sh - 1;
for (int i = 1; i <= N; i++) t[i].h = lower_bound(&Sh[1], &Sh[toth + 1], t[i].h) - Sh;
for (int i = 1; i <= N; i++) Sv[++totv] = t[i].v;
sort(&Sv[1], &Sv[totv + 1]); totv = unique(&Sv[1], &Sv[totv + 1]) - Sv - 1;
for (int i = 1; i <= N; i++) t[i].v = lower_bound(&Sv[1], &Sv[totv + 1], t[i].v) - Sv;
for (int i = 1; i <= N; i++) f[0][i] = f[1][i] = g[0][i] = g[1][i] = 1;
Div(1, N, 0); reverse(&t[1], &t[N + 1]);
for (int i = 1; i <= N; i++) t[i].v = N + 1 - t[i].v, t[i].h = N + 1 - t[i].h;
Div(1, N, 1);
int ans = 0; double ss = 0;
for (int i = 1; i <= N; i++) ans = max(ans, f[0][i]);
for (int i = 1; i <= N; i++) if (f[0][i] == ans) ss += g[0][i];
printf("%d\n", ans);
for (int i = 1; i <= N; i++)
if (f[0][i] + f[1][i] - 1 != ans) printf("0.000000 ");
else printf("%0.6lf ", g[0][i] * g[1][i] / ss);
printf("\n");
return 0;
}
【LG2481】[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 某国为了防御敌国的导弹 ...
- 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 ...
随机推荐
- 如何在两个月的时间内发表一篇EI/SCI论文-我的时间管理心得
在松松垮垮的三年研究生时期,要说有点像样的成果,也只有我的小论文可以谈谈了.可能有些厉害的角色研究生是丰富而多彩的,而大多数的同学在研究生阶段可能同我一样,是慢悠悠的渡过的,而且可能有的还不如我,我还 ...
- Intellij IDEA 开启自动保存功能
IntelljJ IDEA关于文件自动保存功能主要有两种方式: 切换到其他应用时保存变化(默认使能) 设置路径:Settings >> Apperance & Behavior & ...
- 三·管理和配置Subversion(基于Centos7)
基于上一篇文章 二·安装Subversion(基于Centos7)中安装的Subversion,本篇文章讲述Subversion的管理和配置 1.添加环境变量 输入命令vi /etc/profile ...
- PHP中使用substr()截取字符串出现中文乱码问题该怎么办
一.使用mbstring扩展库的mb_substr()截取就不会出现乱码了. 可以用mb_substr()/mb_strcut()这个函数,mb_substr()/mb_strcut()的用法与sub ...
- 可决系数R^2和MSE,MAE,SMSE
波士顿房价预测 首先这个问题非常好其实要完整的回答这个问题很有难度,我也没有找到一个完整叙述这个东西的资料,所以下面主要是结合我自己的理解和一些资料谈一下r^2,mean square error 和 ...
- 解决FileUpload上传大文件报错
<system.webServer> <security> <requestFiltering> <requestLimits maxAllowedConte ...
- Vue教程:Class 与 Style 绑定(四)
绑定 HTML Class 对象语法 ①.添加单个class: <div v-bind:class="{ active: isActive }"></div> ...
- 洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)
题目描述 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战. 游戏中有一个叫做“LCT” 的挑 ...
- CentOS7.5二进制安装MySQL-5.6.40
安装依赖 yum install -y gcc gcc-c++ automake autoconf yum -y install cmake bison-devel ncurses-devel lib ...
- 利用CSS3选择器实现表格的斑马纹
要用到的Css3选择器 element:nth-child(number){ } 选择器匹配属于其父元素的第 number 个子元素 参数 Number odd 奇数 even 偶数 W3School ...