这个我们发现排好序后跑答案是最大的
然后就是维护一个支持插入的序列 我本来想把权值相同的压成一段 然后就gg 出门左转神犇学弟博客
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=500005;
struct abcd{
int a,b; bool null;
abcd(){ null=1;}
abcd(int a,int b):a(a),b(b),null(0) { }
friend abcd operator + (abcd &A,abcd &B){
if (A.null) return B;
if (B.null) return A;
return abcd(A.a+B.a,min(A.b+B.a,B.b));
}
}T[N<<2];
int n,a[N];
int idx[N],back[N];
bool cmp(int x,int y){
return a[x]==a[y]?x<y:a[x]<a[y];
}
inline void Modify(int x,int l,int r,int t,abcd a){
if (l==r) return void(T[x]=a);
int mid=(l+r)>>1;
if (t<=mid) Modify(x<<1,l,mid,t,a);
else Modify(x<<1|1,mid+1,r,t,a);
T[x]=T[x<<1]+T[x<<1|1];
}
int Ret;
inline void Query(int x,int l,int r,int ql,int qr){
if (ql>qr) return;
if (ql<=l && r<=qr){
if (!T[x].null) Ret=min(Ret+T[x].a,T[x].b);
return;
}
int mid=(l+r)>>1;
if (ql<=mid) Query(x<<1,l,mid,ql,qr);
if (qr>mid) Query(x<<1|1,mid+1,r,ql,qr);
}
int c[N];
inline void add(int x){
for (int i=x;i<=n;i+=i&-i)
c[i]++;
}
inline int sum(int x){
int ret=0;
for (int i=x;i;i-=i&-i)
ret+=c[i];
return ret;
}
int sx[N],icnt;
int main(){
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n);
for (int i=1;i<=n;i++) read(a[i]),sx[++icnt]=a[i],idx[i]=i;
sort(idx+1,idx+n+1,cmp); sort(sx+1,sx+icnt+1);
for (int i=1;i<=n;i++) back[idx[i]]=i;
for (int i=1;i<=n;i++){
Modify(1,1,n,back[i],abcd(1,a[i]));
add(back[i]);
int L=0,R=n+1,MID;
while (L+1<R)
if (-sum((MID=(L+R)>>1)-1)>a[idx[MID]])
L=MID;
else
R=MID;
Ret=-sum(L);
Query(1,1,n,L+1,n);
printf("%d\n",Ret);
}
return 0;
}