You a given a permutation p1,p2,…,pnp1,p2,…,pn of size nn. Initially, all elements in pp are frozen. There will be nn stages that these elements will become available one by one. On stage ii, the element pkipki will become available.
For each ii, find the longest increasing subsequence among available elements after the first ii stages.
Input
The first line of the input contains an integer T(1≤T≤3)T(1≤T≤3), denoting the number of test cases.
In each test case, there is one integer n(1≤n≤50000)n(1≤n≤50000) in the first line, denoting the size of permutation.
In the second line, there are nn distinct integers p1,p2,...,pn(1≤pi≤n)p1,p2,...,pn(1≤pi≤n), denoting the permutation.
In the third line, there are nn distinct integers k1,k2,...,kn(1≤ki≤n)k1,k2,...,kn(1≤ki≤n), describing each stage.
It is guaranteed that p1,p2,...,pnp1,p2,...,pn and k1,k2,...,knk1,k2,...,kn are generated randomly.
Output
For each test case, print a single line containing nn integers, where the ii-th integer denotes the length of the longest increasing subsequence among available elements after the first ii stages.
Sample Input
1
5
2 5 3 1 4
1 4 5 3 2
Sample Output
1 1 2 3 3
主要是因为数据全部随机(文中提出),所以直接暴力复杂度的话期望也不高。。。附赠一个带路径的LIS模板
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6 + 10;
int a[maxn], b[maxn], c[maxn], pos[maxn], ans[maxn];
int cnt, tmplong, sum, n;
void solve() {
cnt = sum = 0;
for (int i = 0; i <= n; i++) pos[i] = 0;//这个位置数组别忘记初始化~~
for (int i = 1; i <= n; i++) {
if (a[i] == 0) continue;//为0表示这个位置上的数还不能用
if (cnt == 0 || a[i] > ans[cnt]) {
ans[++cnt] = a[i];
pos[i] = cnt;//记录路径,a[i]这个数在哪儿个位置
}
else {
int index = lower_bound(ans + 1, ans + cnt + 1, a[i]) - ans;
ans[index] = a[i];
pos[i] = index;//记录路径,a[i]这个数在哪儿个位置
}
}
tmplong = cnt;
int maxx = 5201314;//因为今天七夕节,哈哈哈~~开玩笑的~~这个最大值不加也行
sum = 0;
for (int i = n; i >= 1; i--) {//存lis里有什么数
if (!cnt) break;
if (pos[i] == cnt && maxx > a[i]) {// 这个 maxx>a[i] 没有也可以
cnt--;
c[sum++] = a[i];
maxx = a[i];//不加也行,我是为了保证正确性,其实没啥鸟用
}
}
sort(c, c + sum);//不从小到大排序没法用库函数二分
}
int main() {
int t;
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
cin >> b[i];
solve();
stack<int>res;
for (int i = n; i >= 1; i--) {
int pos = lower_bound(c, c + sum, a[b[i]]) - c;
if (c[pos] != a[b[i]]) {
res.push(tmplong);
a[b[i]] = 0;
}
else {
res.push(tmplong);
a[b[i]] = 0;
solve();
}
}
while (!res.empty()) {
cout << res.top(); res.pop();
if (!res.empty())cout << " ";
}
cout << "\n";
}
return 0;
}