坑点:
注意在二分的时候不要减一,比如:
if(key < mid){
r = mid - 1;
}
这样的话可能把我们需要改的数据跳过去。。。。
坑死我了。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <queue>
#include <cmath>
#include <algorithm>
#include <map>
typedef long long int lli;
using namespace std;
int dp[100100];
int cnt;
int a[100100];
int ans[100100];
int bs(int key){
int l = 1,r = cnt;
int mid = (l+r) >> 1;
while(l < r && r-l > 3){
mid = (l+r) >> 1;
if(dp[mid] == key){
return mid;
}
if(dp[mid] > key)
r = mid;
else
l = mid;
}
for(int i = l;i <= r;i++){
if(dp[i] >= key){
dp[i] = key;
return i;
}
}
return 233333333333;
}
int main(){
int t;
cin>>t;
int n;
while(t--){
cnt = 1;
scanf("%d",&n);
for(int i = 1;i <= n;i++){
scanf("%d",a+i);
}
dp[1] = a[1];
ans[1] = 1;
for(int i = 2;i <= n;i++){
if(a[i] > dp[cnt]){
dp[++cnt] = a[i];
ans[i] = cnt;
}
else{
ans[i] = bs(a[i]);
}
}
for(int i = 1;i <= n;i++){
if(i != 1) printf(" ");
printf("%d",ans[i]);
}
puts("");
}
}