MarsOJ 上的题,是 B3637 最长上升子序列 的加强版,n≤5×103,1≤ai≤109,20 个点 WA 了一个,Read 4, Expected 5.
我试着跟二分求解 LIS 的代码对拍,但是拍了十几分钟还是没有出错。我的代码是哪里出了问题,谢谢!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e5 + 10;
ll n, m, a[N], b[N], c[N], t[N], f[N];
inline ll read() {
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch&15);ch=getchar();}
return x*f;
}
ll lowbit(ll x) {
return x & (-x);
}
void add(ll i, ll x) {
ll pos = i;
while (pos <= n) {
t[pos] = max(t[pos], x);
pos += lowbit(pos);
}
}
ll ask(ll i) {
ll res = 0;
while (i) {
res = max(res, t[i]);
i -= lowbit(i);
}
return res;
}
ll query(ll x) {
return lower_bound(b + 1, b + m + 1, x) - b;
}
int main() {
n=read();
for(ll i=1;i<=n;i++) {
a[i] = read(); a[i] ++; b[i] = a[i];
}
sort(b + 1, b + n + 1);
m = unique(b + 1, b + n + 1) - b;
for (int i=1;i<=n;i++) {
c[i]=query(a[i]);
}
for(ll i=1;i<=n;i++) {
f[i] = ask(c[i]-1) + 1;
add(c[i], f[i]);
}
ll ans=0;
for(ll i=1;i<=n;i++) {
ans=max(ans,f[i]);
}
cout << ans << "\n";
return 0;
}