【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 ...
随机推荐
- eclipse run on server 时 报的错误APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
写这篇日记记录一下自己的愚蠢行为. 具体报错如下: 信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ ...
- SOJ4459 skysky's game(贪心+优先队列)
天天最近迷上了天天爱消除游戏,现在他觉得这个游戏已经没有意思了.所以他发明一个新的消除游戏.有n堆糖果,每一个糖果有一个重量w,天天每次都选择两个糖果合并为一个糖果,新的糖果的重量等于这两个糖果的重量 ...
- 【剑指offer】字符串的组合
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/26405471 转载请注明出处:http:// ...
- 汇编试验四:[bx] 和 loop 的使用
预备知识: 段前缀的使用: ffff:0~ffff:b 和 0020:0~0020:b 的数据: 一次循环的复制效果: 但是,这种方式DS的数据得修改: Source Code: assume cs: ...
- Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】
任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per tes ...
- 阅读layim代码小记,监听事件实现方法
(function (win) { //注册事件 var chat = function () { $('#open').on('click', function () { sendMessage() ...
- VC++ MFC SDI/MDI Ribbon程序的停靠窗格被关闭后如何再次显示
VC++ 创建基于MFC的SDI应用程序,Visual Studio风格的主界面如下图所示,在该主界面上的视图菜单下包含有队对各个可停靠窗格显示或隐藏的控制菜单项.而基于Ribbon风格的应用程序,所 ...
- C# 实现Excel读取接口写入数据
[Route("adm/getInfo")] [HttpGet] public string GetInfo() { var types = typeof(GCP.Server.W ...
- 解决pycharm无法导入本地包的问题
在用python写爬虫程序时,import 行无法通过,具体情况如下: pycharm运行程序后,程序pass了,但是出现了警告,如下图所示: 这是由于该程序不在根目录下,无法导入本地包,解决办法如下 ...
- 不推荐在iOS的浏览器应用上使用click和mouseover
iOS上的Safari也支持click 和mouseover等传统的交互事件,只是不推荐在iOS的浏览器应用上使用click和mouseover,因为这两个事件是为了支持鼠标点击而设计 出来的.Cli ...