题目链接: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' : ' ');
}
}

最新文章

  1. 关于Qt creator 无法使用fcitx输入中文的问题折腾
  2. vs2013源码编译zlib 1.2.8
  3. APDU
  4. java正则表达式小练习(IP地址检测、排序,叠词的处理,邮件地址的获取)
  5. 第一次写python
  6. spoj 1436
  7. 198. House Robber
  8. 第一章 00 StringUtil.cpp和StringUtil.hh分析
  9. uva 10012
  10. codeforces 613A. Peter and Snow Blower
  11. ThinkPHP 自动创建数据、自动验证、自动完成详细例子介绍(十九)
  12. [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念
  13. Python之旅_计算机基础入门
  14. Hillstone目的地址转换DNAT配置
  15. 南阳236----心急的C小加
  16. Python3基础 访问在线的有道词典
  17. 微信小程序 - 提示消息组件
  18. bzoj 3262
  19. Windows上建立、取消共享文件夹
  20. python初步学习-python模块之 os

热门文章

  1. html+css 在图片上添加文字
  2. Spring Batch Hello World
  3. 【leetcode】581. Shortest Unsorted Continuous Subarray
  4. js 文件下载 兼容ie
  5. react native之使用 Fetch进行网络数据请求
  6. js自执行函数前加个分号是什么意思?
  7. adb打开系统设置的命令
  8. Laya layout算法
  9. 一些性能优化的tips
  10. .NET(c#) 移动APP开发平台 - Smobiler(2) - 平台介绍