首页 > 其他分享 >LibreOJ L2056 「TJOI / HEOI2016」序列

LibreOJ L2056 「TJOI / HEOI2016」序列

时间:2023-01-18 22:11:23浏览次数:64  
标签:node Min int TJOI mid CDQ HEOI2016 L2056 DP

https://loj.ac/p/2056


CDQ 优化 DP 模板?


首先定义对于第 \(x\) 个数其可以变为的最小值为 \(Min_x\),最大值为 \(Max_x\),初始为 \(M_x\)。

因为最多只会变一次数,不难想到暴力 DP 的方法:
设 \(dp_i\) 为以 \(i\) 结尾不降子序列的最长长度,可得转移方程:
\(dp_i=\max\{dp_j\}+1(i<j\ \operatorname{and}\ M_j\le Min_i\ \operatorname{and}\ Max_j\le M_i)\)

然后发现这就是个 CDQ 优化 DP 的板子,第一维为 \(i\),第二维左边为 \(M_i\) 右边为 \(Min_i\),用树状数组记录前缀最大值更新即可。
CDQ 优化 DP OI - Wiki 指路:https://oi-wiki.org/misc/cdq-divide/#cdq-分治优化-1d1d-动态规划的转移


# include <bits/stdc++.h>
using namespace std;
const int N = 100000;
struct node {
	int id, M, Min, Max, ans;
} a [N + 10], p [N + 10];
int t [N + 10];
int k;
void add (int x, int y) {
	for (int i = x; i <= k; i += i & -i) {
		t [i] = max (t [i], y);
	}
	return ;
}
int query (int x) {
	int ans = 0;
	for (int i = x; i; i -= i & -i) {
		ans = max (ans, t [i]);
	}
	return ans;
}
int use [N + 10];
void clear (int x) {
	for (int i = x; i <= k; i += i & -i) {
		t [i] = 0;
	}
	return ;
}
void CDQ (int l, int r) {
	if (l == r) {
		a [l] .ans = max (a [l] .ans, 1);
		return ;
	}
	int mid = (l + r) >> 1;
	CDQ (l, mid);
	sort (a + l, a + mid + 1, [&] (node x, node y) {
		return x .M < y .M;
	});
	sort (a + mid + 1, a + r + 1, [&] (node x, node y) {
		return x .Min < y .Min;
	});
	int cnt = 0;
	for (int i = l, j = mid + 1; j <= r; ++ j) {
		while (i <= mid && a [i] .M <= a [j] .Min) {
			use [++ cnt] = a [i] .Max;
			add (a [i] .Max, a [i] .ans);// 更新最大值
			++ i;
		}
		a [j] .ans = max (a [j] .ans, query (a [j] .M) + 1);// 查询最大值 + 1
	}
	while (cnt) {
		clear (use [cnt]);
		-- cnt;
	}
	sort (a + mid + 1, a + r + 1, [&] (node x, node y) {
		return x .id < y. id;
	});
	CDQ (mid + 1, r);
	return ;
}
int main () {
	int n, m;
	scanf ("%d %d", & n, & m);
	for (int i = 1; i <= n; ++ i) {
		int x;
		scanf ("%d", & x);
		a [i] .id = i;
		a [i] .M = a [i] .Max = a [i] .Min = x;
		a [i] .ans = 0;
	}
	while (m --) {
		int x, y;
		scanf ("%d %d", & x, & y);
		a [x] .Min = min (a [x] .Min, y);
		a [x] .Max = max (a [x] .Max, y);
	}
	for (int i = 1; i <= n; ++ i) {
		k = max (k, a [i] .Max);
	}
	CDQ (1, n);
	int ans = 0;
	for (int i = 1; i <= n; ++ i) {
		ans = max (ans, a [i] .ans);
	}
	printf ("%d", ans);
	return 0;
}

标签:node,Min,int,TJOI,mid,CDQ,HEOI2016,L2056,DP
From: https://www.cnblogs.com/lhzQAQ/p/17060734.html

相关文章

  • Luogu P4592 [TJOI2018]异或 做题记录
    随机跳的。树上维护序列,显然树剖。维护异或,显然01trie。01trie维护区间异或,显然可持久化一下。看到时限很大,显然可以双log。于是跑一边树剖,再根据id暴力建一个可......
  • Luogu P4591 [TJOI2018] 碱基序列
    链接难度:\(\texttt{省选/NOI-}\)有\(k\)组,每一组有\(a_i\)个字符串\(t_{k,a_i}\),询问分别在每一组选一个字符串拼成的字符串在文本串\(s\)出现的个数的所有情况......
  • LibreOJ L2576 「TJOI2018」str
    链接难度:\(\texttt{?}\)有\(k\)组,每一组有\(a_i\)个字符串\(t_{k,a_i}\),询问分别在每一组选一个字符串拼成的字符串在文本串\(s\)出现的个数的所有情况的总和对......
  • 美国亚马逊移动电源UL2056测试流程
    UL2056标准是针对移动电源终端产品推出的安全标准。UL2056标准回应全球移动电源对安全标准的需求,避免消费者受到人身及财产的损害,亦使制造商减低承受昂贵的产品回收及品牌......
  • [TJOI2015]组合数学
    [\(TJOI2015\)]组合数学链接:https://www.luogu.com.cn/problem/P3974题面:有一个\(n\timesm\)的网格,有些格子里有财宝,每次从左上角出发,只能往右或下走且每一次经过一......
  • [HEOI2016/TJOI2016]排序
    https://www.luogu.com.cn/problem/P2824题解:仔细思考可以发现这道题与https://arc101.contest.atcoder.jp/tasks/arc101_b?lang=en是等价的。二分之后原问题就转化为了......
  • P3845 [TJOI2007]球赛
    简要题意\(T\)组数据,每一组数据给出\(n\)个数对\((a,b)\)。你需要将其分为几组,使得组单调不降。求最小组数。思路模拟赛考的题。先来介绍Dilworth定理:对于任意......
  • LG_P4588 [TJOI2018] 数学计算 题解
    LuoguP4588题解这个玩意还是挺好想到的,也不难看出他是一个线段树。没想到可以评上蓝。考虑每次操作对于答案的贡献。由于\(x=1\),所以我们相当于是在维护一堆数的积,初始......
  • 题解 P3974【[TJOI2015]组合数学】
    postedon2022-10-2814:11:41|under题解|sourceproblem给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走。问至少走多少次才能将财宝捡完。此对......
  • P2824 [HEOI2016/TJOI2016]排序
    P2824[HEOI2016/TJOI2016]排序题目大意这个难题是这样子的:给出一个\(1\)到\(n\)的排列,现在对这个排列序列进行\(m\)次局部排序,排序分为两种:0lr表示将区间\(......