Another LIS
There is a sequence firstly empty. We begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. Now, we want to know length of the LIS (Longest Increasing Subsequence) after every time's add.
Input
An integer T (T <= 10), indicating there are T test cases.
For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
Output
For the k-th test case, first output "Case #k:" in a separate line, then followed N lines indicating the answer. Output a blank line after every test case.
Sample Input
1 3 0 0 2
Sample Output
Case #1: 1 1 2
Hint
In the sample, we add three numbers to the sequence, and form three sequences. a. 1 b. 2 1 c. 2 1 3
AC代码
//#include<bits/stdc++.h>
#define _CRT_SBCURE_NO_DEPRECATE
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
//#define UP(i,x,y) for(int i=x;i<=y;i++)
//#define DOWN(i,x,y) for(int i=x;i>=y;i--)
//#define sd(x,y,z) scanf("%d%d%d", &x, &y, &z)
//#define sd(x,y) scanf("%d%d", &x, &y)
#define sd(x) scanf("%d", &x)
//#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
#define MOD 1000000007
const int maxn = 100100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
int n, m, t, _n;
int dat[maxn<<2];
int ans;
struct node
{
int num;
int pos;
int endpos;
};
node arr[maxn];
void add(int k, int v)
{
k += n-1;
dat[k] = v;
while(k)
{
k = (k-1)/2;
dat[k] = dat[k*2+1] + dat[k*2+2];
}
}
void init(int _n)
{
n = 1;
while(n < _n) n<<=1;
memset(dat, 0, sizeof dat);
for(int i = 0; i < _n; i++) add(i,1);
}
int query(int v, int k, int l, int r)
{
if(r-l==1)
{
return k-n+1;
}
else
{
if(dat[2*k+1]>v)
{
return query(v, 2*k+1, l, (l+r)/2);
}
else
{
return query(v-dat[2*k+1], 2*k+2, (l+r)/2, r);
}
}
}
bool cmp(node &a, node &b)
{
return a.endpos<b.endpos;
}
int len = 0;
int dp[maxn];
int Find(int v, int l, int r)
{
if(l>r) return l;
else
{
if(dp[(l+r)/2]<v)
{
return Find(v, (l+r)/2+1, r);
}
else
{
return Find(v, l, (l+r)/2-1);
}
}
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d", &t); int a = 1;
while (t--)
{
scanf("%d", &_n);
init(_n);
for(int i = 0; i < _n; i++)
{
scanf("%d", &arr[i].pos);
arr[i].num = i+1;
dp[i] = 0;
}
for(int i = _n-1; i >= 0; i--)
{
arr[i].endpos = query(arr[i].pos, 0, 0, n);
add(arr[i].endpos, 0);
}
len = 0;
printf("Case #%d:\n", a++);
//sort(arr, arr+_n, cmp);
for(int i = 0; i < _n; i++)
{
int k = Find(arr[i].endpos, 1, len);
dp[k] = arr[i].endpos;
len = max(k, len);
printf("%d\n",len);
}
printf("\n");
}
return 0;
}