[2019杭电多校第六场][hdu6635]Nonsense Time
2024-10-07 09:39:13
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6635
题意是说一开始所有数都冻结,第i秒会解冻第ki个数,求每秒状态下的最长上上升子序列长度。
这种题一想添加操作就不好实现,所以干脆反着来,想删除操作。
从第n秒开始往前遍历,每次都会冻结一个数,这时判断一下这个数是否一定要在最长上升子序列里。
使用二分的方法求最长上升子序列,并且每次求完子序列后可以处理出那些位置是必须在最长上升子序列里的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 5e4 + ;
int a[maxn], vis[maxn], ans[maxn], d[maxn], in[maxn], dp[maxn];
int len;
void slove(int n) {
len = ;
for (int i = ; i <= n; i++) {
if (a[i] != ) {
int pos = lower_bound(d + , d + + len, a[i]) - d;
if (pos > len)
d[++len] = a[i];
else
d[pos] = a[i];
dp[i] = pos;
}
}
int q = len, limit = n;
for (int i = n; i >= ; i--) {
if (dp[i] == q && a[i] <= limit && a[i] != ) {
limit = a[i];
in[i] = ;
q--;
}
else
in[i] = ;
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%d", &a[i]);
for (int i = ; i <= n; i++)
scanf("%d", &vis[i]);
slove(n);
for (int i = n; i >= ; i--) {
ans[i] = len;
a[vis[i]] = ;
if (in[vis[i]])slove(n);
}
for (int i = ; i <= n; i++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
}
}
最新文章
- 关于Qt creator 无法使用fcitx输入中文的问题折腾
- vs2013源码编译zlib 1.2.8
- APDU
- java正则表达式小练习(IP地址检测、排序,叠词的处理,邮件地址的获取)
- 第一次写python
- spoj 1436
- 198. House Robber
- 第一章 00 StringUtil.cpp和StringUtil.hh分析
- uva 10012
- codeforces 613A. Peter and Snow Blower
- ThinkPHP 自动创建数据、自动验证、自动完成详细例子介绍(十九)
- [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念
- Python之旅_计算机基础入门
- Hillstone目的地址转换DNAT配置
- 南阳236----心急的C小加
- Python3基础 访问在线的有道词典
- 微信小程序 - 提示消息组件
- bzoj 3262
- Windows上建立、取消共享文件夹
- python初步学习-python模块之 os