【HDU6635】Nonsense Time

阅读: 评论:0

【HDU6635】Nonsense Time

【HDU6635】Nonsense Time

题目大意:给定一个长度为 N 的序列,开始时所有的位置都不可用,每经过一个时间单位,都会有一个位置被激活。现给定激活顺序的序列,求每次激活之后全局的最长上升子序列的长度,保证数据随机。

题解:
引理:数据随机的情况下,一个长度为 (N) 的序列的最长上升子序列的期望长度为 (O(sqrt n))。(暂时不会证明qaq)
发现若正序考虑,判断每次被激活位置的值是否对当前全局最优解有贡献这一操作所消耗的复杂度过高,无法接受。考虑时间倒流,即:初始时所有位置的值均被激活,每次会有一个位置的值无效。根据引理可知,(i) 个数字的 (LIS) 的期望值为 (O(sqrt i)),即:每 (sqrt n) 个数字无效时,全局 (LIS) 才会减少 1。因此,只需要判断每次无效的数是否在全局 (LIS) 中,若存在,则暴力重构全局最优解,否则直接输出答案即可。时间复杂度为 (O(nsqrt nlogn))。

代码如下

#include <bits/stdc++.h>
using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(0);int T;cin >> T;while (T--) {int n;cin >> n;vector<int> a(n), melt(n);for (int i = 0; i < n; i++) {cin >> a[i];    }for (int i = 0; i < n; i++) {cin >> melt[i];melt[i]--;}vector<bool> frozen(n), book(n);vector<int> ans(n), dp(n), pos(n);auto RunLIS = [&]() {fill(dp.begin(), dp.end(), 1e9);fill(book.begin(), d(), 0);fill(pos.begin(), d(), -1);int r = 0;for (int i = 0; i < n; i++) {if (frozen[i] == 0) {int id = lower_bound(dp.begin(), dp.end(), a[i]) - dp.begin();if (dp[id] == 1e9) {r = max(r, id);}dp[id] = a[i], pos[i] = id;}}for (int i = n - 1, now = 1e9, len = r; i >= 0; i--) {if (len < 0) break;if (pos[i] == len && a[i] < now) {now = a[i];len--;book[i] = 1;}}return r + 1;};int ret = RunLIS();for (int i = n - 1; i >= 0; i--) {ans[i] = ret;frozen[melt[i]] = 1;if (book[melt[i]] == 1) {ret = RunLIS();}}cout << ans[0];for (int i = 1; i < n; i++) {cout << " " << ans[i];}cout << endl;}return 0;
}

转载于:.html

本文发布于:2024-01-31 16:20:00,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170668920029812.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:Nonsense   Time
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23