# [Tjoi2013]最长上升子序列 树状数组+二分

Description

Sample Input
3
0 0 2

Sample Output
1
1
2

#include <cstdio>
#include <cstring>

using namespace std;
int _max(int x, int y) {return x > y ? x : y;}

int n, a[110000], s[110000];

int lowbit(int x) {return x & -x;}
void change1(int x, int c) {
for(int i = x; i <= n; i += lowbit(i)) s[i] += c;
}
void change2(int x, int c) {
for(int i = x; i <= n; i += lowbit(i)) s[i] = _max(s[i], c);
}
int getsum(int x) {
int sum = 0;
for(int i = x; i >= 1; i -= lowbit(i)) sum += s[i];
return sum;
}
int getmax(int x) {
int maxx = 0;
for(int i = x; i >= 1; i -= lowbit(i)) maxx = _max(maxx, s[i]);
return maxx;
}

int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i]++;
for(int i = n; i >= 1; i--) {
int x = a[i];
int l = a[i], r = n;
while(l <= r) {
int mid = (l + r) / 2;
if(getsum(mid) <= mid - x) a[i] = mid, r = mid - 1;
else l = mid + 1;
}
change1(a[i], 1);
}
int ans = 0;
memset(s, 0, sizeof(s));
for(int i = 1; i <= n; i++) {
int s = getmax(a[i] - 1) + 1;
ans = _max(ans, s);
change2(a[i], s);
printf("%d\n", ans);
}
return 0;
}

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120