首页 > 其他分享 >P2487 [SDOI2011] 拦截导弹

P2487 [SDOI2011] 拦截导弹

时间:2024-10-19 09:21:05浏览次数:8  
标签:拦截导弹 return int SDOI2011 ans P2487 include type define

Sol

两个限制的导弹拦截。

设 \(f_i\) 表示以 \(i\) 结尾的最长 LIS 显然可以得到暴力转移方程 \(f_i=\displaystyle\max_{j=1,a_j\ge a_i,b_j \ge b_i}^{i-1}f_j+1\),考虑到是三维偏序,所以用 CDQ 分治优化即可。

离散化不要忘记排序!

Code

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cassert>
#include <chrono>
#include <random>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\MPC\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
    if (y > x) return x = y,true;
    return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
    if (y < x) return x = y,true;
    return false;
}
LL power (LL a,LL b,LL p) {
    LL ans = 1;
    while (b) {
        if (b & 1) ans = ans * a % p;
        a = a * a % p;
        b >>= 1;
    }
    return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << s << endl
const int N = 50010;
int n;
struct node {
	int a,b,id;
}a[N],_a[N];
struct ans_type {
	int v;
	double cnt;
	ans_type (int _v = 0,double _cnt = 0) {
		v = _v,cnt = _cnt;
	}
}f[N],g[N];
ans_type operator + (ans_type a,ans_type b) {return ans_type (a.v + b.v,a.cnt + b.cnt);}
ans_type max (ans_type a,ans_type b) {
	if (a.v != b.v) return a.v > b.v ? a : b;
	return ans_type (a.v,a.cnt + b.cnt);
}
int lowbit (int x) {return x & -x;}
struct BIT_suf {
	ans_type c[N];
	void clear (int x) {for (int i = x;i;i -= lowbit (i)) c[i] = ans_type (0,0);}
	void modify (int x,ans_type d) {for (int i = x;i;i -= lowbit (i)) c[i] = max (c[i],d);}
	ans_type query (int x) {
		ans_type ans;
		for (int i = x;i <= n;i += lowbit (i)) ans = max (ans,c[i]);
		return ans;
	}
}c1;
struct BIT_pre {
	ans_type c[N];
	void clear (int x) {for (int i = x;i <= n;i += lowbit (i)) c[i] = ans_type (0,0);}
	void modify (int x,ans_type d) {for (int i = x;i <= n;i += lowbit (i)) c[i] = max (c[i],d);}
	ans_type query (int x) {
		ans_type ans;
		for (int i = x;i;i -= lowbit (i)) ans = max (ans,c[i]);
		return ans;
	}
}c2;
bool cmp1 (node x,node y) {return x.a > y.a;}
bool cmp2 (node x,node y) {return x.a < y.a;}
void solve1 (int l,int r) {
	if (l == r) return ;
	int mid = l + r >> 1;
	solve1 (l,mid);
	for (int i = l;i <= r;i++) a[i] = _a[i];
	sort (a + l,a + mid + 1,cmp1),sort (a + mid + 1,a + r + 1,cmp1);
	for (int i = mid + 1,j = l;i <= r;i++) {
		while (j <= mid && a[j].a >= a[i].a) c1.modify (a[j].b,f[a[j].id]),j++;
		f[a[i].id] = max (f[a[i].id],c1.query (a[i].b) + ans_type (1,0));
	}
	for (int i = l;i <= mid;i++) c1.clear (a[i].b);
	solve1 (mid + 1,r);
}
void solve2 (int l,int r) {
	if (l == r) return ;
	int mid = l + r >> 1;
	solve2 (l,mid);
	for (int i = l;i <= r;i++) a[i] = _a[i];
	sort (a + l,a + mid + 1,cmp2),sort (a + mid + 1,a + r + 1,cmp2);
	for (int i = mid + 1,j = l;i <= r;i++) {
		while (j <= mid && a[j].a <= a[i].a) c2.modify (a[j].b,g[a[j].id]),j++;
		g[a[i].id] = max (g[a[i].id],c2.query (a[i].b) + ans_type (1,0));
	}
	for (int i = l;i <= mid;i++) c2.clear (a[i].b);
	solve2 (mid + 1,r);
}
int main () {
	cin >> n;
	for (int i = 1;i <= n;i++) cin >> a[i].a >> a[i].b,a[i].id = i;
	vector <int> all;
	auto find = [&](int x) {return lower_bound (all.begin (),all.end (),x) - all.begin () + 1;};
	for (int i = 1;i <= n;i++) all.pb (a[i].b);
	sort (all.begin (),all.end ());
	all.erase (unique (all.begin (),all.end ()),all.end ());
	for (int i = 1;i <= n;i++) a[i].b = find (a[i].b);
	for (int i = 1;i <= n;i++) _a[i] = a[i];
	for (int i = 1;i <= n;i++) f[i] = g[i] = ans_type (1,1);
	solve1 (1,n);
	reverse (_a + 1,_a + n + 1);
	solve2 (1,n);
	ans_type ans;
	for (int i = 1;i <= n;i++) ans = max (ans,f[i]);
	cout << ans.v << endl;
	// for (int i = 1;i <= n;i++) cout << 0 << ' ';
	// cout << endl;
	// return 0;
	for (int i = 1;i <= n;i++) {
		if (f[i].v + g[i].v - 1 == ans.v) cout << fixed << setprecision (5) << f[i].cnt * g[i].cnt / ans.cnt << ' ';
		else cout << 0 << ' ';
	}
	cout << endl;
	return 0;
}

标签:拦截导弹,return,int,SDOI2011,ans,P2487,include,type,define
From: https://www.cnblogs.com/incra/p/18475492

相关文章

  • [SDOI2011] 工作安排——费用流
    [SDOI2011]工作安排题目描述你的公司接到了一批订单。订单要求你的公司提供\(n\)类产品,产品被编号为\(1\simn\),其中第\(i\)类产品共需要\(C_i\)件。公司共有\(m\)名员工,员工被编号为\(1\simm\)员工能够制造的产品种类有所区别。一件产品必须完整地由一名员工制......
  • [题解] [SDOI2011] 消防
    [题解][SDOI2011]消防tag:图论、树、树的直径题目链接(洛谷):https://www.luogu.com.cn/problem/P2491题目描述给定一棵\(n\)个节点的树,第\(i\)条边有边权\(z_i\)。要求找到树上一条长度不大于\(s\)的简单路径,使得不在路径上的点到该路径的最大距离最小。数据范围:\(1......
  • 南沙C++信奥老师解一本通题 1260:【例9.4】拦截导弹(Noip1999)
    ​【题目描述】某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦......
  • D49 树的直径 P2491 [SDOI2011] 消防
    视频链接: P2491[SDOI2011]消防-洛谷|计算机科学教育新生态(luogu.com.cn)//两次DFS+双指针O(n)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;constintN=300010;intidx,head[N];structedge{intto,w,ne;}e[N<<1]......
  • [SDOI2011] 拦截导弹
    这是CDQ分治优化1D/1D动态规划的模板题(1D/1D动态规划的概念见OI-wiki)一般来说,优化的1D/1D/动态规划,在转移的时候是由不等式作为条件的,所以可以像这样转化为三维偏序用线段树进行如下维护:1.维护区间最大值2.查询区间最大值的某一数组的和代码见下(一定要学会将数组翻转的操作)#......
  • P2495 [SDOI2011] 消耗战
    P2495[SDOI2011]消耗战虚树优化dp模板题考虑\(m=1\)。只需要简单的树形dp,设\(f_i\)表示\(i\)子树中的关键点都到不了\(i\)点的最小代价。转移枚举子节点\(v\),有:若\(v\)点为关键点,\(f_u=f_u+w(u,v)\)。否则,\(f_u=f_u+\min(f_v,w(u,v))\)。如果每次询问都跑一遍......
  • P2487 [SDOI2011] 拦截导弹 题解
    题目链接:拦截导弹约定:本题中提到的\(LDS\)和\(LIS\)不是严格单调,而是非严格单调,即为\(\le或者\ge\)。比较神奇的题,问的东西比较多,我们逐渐拆分:对于第一个问题而言,这个dp方程是很好写的:\[dp[i]=\max{dp[j]}+1(i<j,h[i]\leh[j],v[i]\lev[j])\]其中\(dp[i]\)即......
  • P2495 [SDOI2011] 消耗战
    题意给定一棵有边权的无根树。\(q\)次询问,每次询问\(k\)个点。求断边使得根节点\(1\)与\(k\)个点不连通的最小边权。Sol虚树。\(n^2\)dp是trivial的。考虑优化。注意到其中很多点都是无用的。考虑保留有效点。不难发现,有效点集为询问点两两\(lca\)的集合......
  • P2486 [SDOI2011] 染色
    题目描述给定一棵\(n\)个节点的无根树,共有\(m\)个操作,操作分为两种:将节点\(a\)到节点\(b\)的路径上的所有点(包括\(a\)和\(b\))都染成颜色\(c\)。询问节点\(a\)到节点\(b\)的路径上的颜色段数量。颜色段的定义是极长的连续相同颜色被认为是一段。例如112221......
  • 解题报告P2486 [SDOI2011] 染色
    P2486[SDOI2011]染色题目链接分两段,最后靠同一条重链合树剖加线段树,典中典。这题的线段树维护比较新颖。线段树中维护这个区间左右端点的颜色和颜色段数量。建树和查询和修改时要判断左区间的右端点和右区间的左端点是否颜色相同。如果不相同,直接将段数相加,否则减一。然......