可以发现题目的重点是在第一个部分,因为只要信心值我们求出来了,那么第二问就是一个简单的最长上升子序列问题了,所以接下来只讲第一问。
#include<iostream> #include<cstdio> #include<algorithm> #include<ctime> #include<cmath> #include<cstring> #define ll long long using namespace std; #define lc (o<<1) #define mid (l+r>>1) #define rc ((o<<1)|1) const int maxn=100005; int n,a[maxn],b[maxn],c[maxn],f[maxn]; int ans,r[maxn],sum[maxn*4],lef; inline bool cmp(const int &x,const int &y){ return c[x]<c[y];} void build(int o,int l,int r){ sum[o]=r-l+1; if(l==r) return; build(lc,l,mid),build(rc,mid+1,r); } int query(int o,int l,int r){ sum[o]--; if(l==r) return l; if(sum[lc]>=lef) return query(lc,l,mid); else{ lef-=sum[lc]; return query(rc,mid+1,r);} } inline void umax(int x,int y){ for(;x<=n;x+=x&-x) f[x]=max(f[x],y);} inline int qmax(int x){ int an=0; for(;x;x-=x&-x) an=max(an,f[x]); return an;} inline void solve(){ build(1,1,n); for(int i=n;i;r[i]=i,i--) lef=a[i],b[i]=query(1,1,n); sort(r+1,r+n+1,cmp); memset(f,0,sizeof(f)); for(int i=1,now;i<=n;i++) now=r[i],umax(b[now],qmax(b[now])+1); } int main(){ freopen("amazon.in","r",stdin); freopen("amazon.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=n;i++) scanf("%d",c+i); solve(); printf("%d ",qmax(n)); return 0; }