2019HDU多校第六场——HDU6635 Nonsense Time【树状数组求LIS】

2023-12-31 22:40

本文主要是介绍2019HDU多校第六场——HDU6635 Nonsense Time【树状数组求LIS】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接: HDU6635 Nonsense Time

Time Limit: 14000/14000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Problem Description

You a given a permutation p1,p2,…,pn of size n. Initially, all elements in p are frozen. There will be n stages that these elements will become available one by one. On stage i, the element pki will become available.

For each i, find the longest increasing subsequence among available elements after the first i stages.

Input

The first line of the input contains an integer T(1≤T≤3), denoting the number of test cases.

In each test case, there is one integer n(1≤n≤50000) in the first line, denoting the size of permutation.

In the second line, there are n distinct integers p1,p2,...,pn(1≤pi≤n), denoting the permutation.

In the third line, there are n distinct integers k1,k2,...,kn(1≤ki≤n), describing each stage.

It is guaranteed that p1,p2,...,pn and k1,k2,...,kn are generated randomly.

Output

For each test case, print a single line containing n integers, where the i-th integer denotes the length of the longest increasing subsequence among available elements after the first i stages.

Sample Input

1

5

2 5 3 1 4

1 4 5 3 2

Sample Output

1 1 2 3 3

题意:

给你一个1~n的排列a和排列b,起始状态a中所有数都是冻结的,i时刻a中b[i]这个数解冻,计算出当前a中已解冻的数的最长上升子序列。

分析:

正难则反,考虑倒着处理,按照b倒序冻结a中的数;

第n个时刻所有数都已解冻,树状数组求出当前的LIS并标记当前构成LIS,然后向前更新,如果当前冻结的数不在LIS中,那么不改变,否则再次求解LIS;

可以证明,这样的时间复杂度是O(n\sqrt{n}logn)

Tips:类似链表的方式记录前后指针,给原序列加上前后端点,这样就可以快速的得到冻结某个数之后的序列。

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+7;
int a[maxn],b[maxn],vis[maxn],tag[maxn];
int LIS[maxn],bit[maxn],pre[maxn],nxt[maxn],ans[maxn];
int n;
int lowbit(int x) {return x&-x;}
void getLIS()
{for (int i=nxt[0];i<=n+1;i=nxt[i]){vis[i]=0;int tmp=0,res=a[i];while (res){if(LIS[tmp]<LIS[bit[res]]) tmp=bit[res];res-=lowbit(res);}LIS[i]=LIS[tmp]+1;tag[i]=tmp;res=a[i];while (res<=n+2){if(LIS[bit[res]]<LIS[i]) bit[res]=i;res+=lowbit(res);}}for (int i=nxt[0];i<=n+1;i=nxt[i]){int res=a[i];while (res<=n+2){bit[res]=0;res+=lowbit(res);}}for (int i=n+1;i;i=tag[i]) vis[i]=1;
}
void rua()
{scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]++;a[0]=1;a[n+1]=n+2;for (int i=0;i<=n+1;i++) {pre[i]=i-1;nxt[i]=i+1;vis[i]=bit[i]=0;}bit[n+2]=0;for (int i=1;i<=n;i++) scanf("%d",&b[i]);getLIS();for (int i=n;i;i--){ans[i]=LIS[n+1]-1;int x=b[i];pre[nxt[x]]=pre[x];nxt[pre[x]]=nxt[x];if(vis[x]) getLIS();}for (int i=1;i<n;i++) printf("%d ",ans[i]);printf("%d\n",ans[n]);	
}
int main()
{int t;scanf("%d",&t);while (t--) rua();return 0;
}

 

这篇关于2019HDU多校第六场——HDU6635 Nonsense Time【树状数组求LIS】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/557333

相关文章

C++原地删除有序数组重复项的N种方法

《C++原地删除有序数组重复项的N种方法》给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(... 目录一、问题二、问题分析三、算法实现四、问题变体:最多保留两次五、分析和代码实现5.1、问题分析5.

python中time模块的常用方法及应用详解

《python中time模块的常用方法及应用详解》在Python开发中,时间处理是绕不开的刚需场景,从性能计时到定时任务,从日志记录到数据同步,时间模块始终是开发者最得力的工具之一,本文将通过真实案例... 目录一、时间基石:time.time()典型场景:程序性能分析进阶技巧:结合上下文管理器实现自动计时

Java中数组转换为列表的两种实现方式(超简单)

《Java中数组转换为列表的两种实现方式(超简单)》本文介绍了在Java中将数组转换为列表的两种常见方法使用Arrays.asList和Java8的StreamAPI,Arrays.asList方法简... 目录1. 使用Java Collections框架(Arrays.asList)1.1 示例代码1.

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

MySQL中时区参数time_zone解读

《MySQL中时区参数time_zone解读》MySQL时区参数time_zone用于控制系统函数和字段的DEFAULTCURRENT_TIMESTAMP属性,修改时区可能会影响timestamp类型... 目录前言1.时区参数影响2.如何设置3.字段类型选择总结前言mysql 时区参数 time_zon

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2