#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=400010,M=1111111; const ll inf=1LL<<60; int n,m,q,i,ce,have[N]; ll a[N],e[N],op[N][3]; int POS,tag[M];ll cnt[M],sum[M]; int C;ll NXT,SUM,CNT; int pool[N][3],cp; void build(int x,int a,int b){ if(a==b){ cnt[x]=have[a]; sum[x]=cnt[x]*e[a]; return; } int mid=(a+b)>>1; build(x<<1,a,mid),build(x<<1|1,mid+1,b); cnt[x]=cnt[x<<1]+cnt[x<<1|1]; sum[x]=sum[x<<1]+sum[x<<1|1]; } void change(int x,int a,int b,int c,ll A,ll B){ sum[x]+=A; cnt[x]+=B; if(a==b)return; int mid=(a+b)>>1; if(c<=mid)change(x<<1,a,mid,c,A,B);else change(x<<1|1,mid+1,b,c,A,B); } //tag=pos means zero void getnxt(int x,int a,int b){ if(NXT)return; if(tag[x]==POS)return; if(!cnt[x])return; if(a==b){ NXT=e[a]; return; } int mid=(a+b)>>1; if(C<=mid)getnxt(x<<1,a,mid); getnxt(x<<1|1,mid+1,b); } void eat(int x,int a,int b){ if(SUM>NXT)return; if(tag[x]==POS)return; if(!cnt[x])return; if(b<=C){ if(SUM+sum[x]<=NXT){ SUM+=sum[x]; CNT+=cnt[x]; tag[x]=POS; return; } if(a==b){ //o>(NXT-SUM/e[a]) ll tmp=(NXT-SUM)/e[a]; while(tmp*e[a]+SUM<=NXT)tmp++; //if(tmp>cnt[x]||tmp<1)while(1); pool[++cp][0]=a; pool[cp][1]=tmp; ll val=tmp*e[a]; for(;x;x>>=1)cnt[x]-=tmp,sum[x]-=val; SUM+=val; CNT+=tmp; return; } } int mid=(a+b)>>1; if(C>mid)eat(x<<1|1,mid+1,b); eat(x<<1,a,mid); } inline int lower(ll x){ int l=1,r=m,t,mid; while(l<=r)if(e[mid=(l+r)>>1]>=x)r=(t=mid)-1;else l=mid+1; return t; } inline int query(ll A,ll B){ int ans=0; cp=0; while(A<B){ //>=A C=lower(A); NXT=0; getnxt(1,1,m); NXT=min(NXT,B-1); C--; SUM=A; CNT=0; //SUM>NXT eat(1,1,m); if(SUM<=NXT)return -1; A=SUM; ans+=CNT; } return ans; } int main(){ scanf("%d",&n); e[ce=1]=0; for(i=1;i<=n;i++)scanf("%lld",&a[i]),e[++ce]=a[i]; scanf("%d",&q); for(i=1;i<=q;i++){ scanf("%lld%lld",&op[i][0],&op[i][1]); if(op[i][0]==1)scanf("%lld",&op[i][2]); if(op[i][0]==2)e[++ce]=op[i][1]; } sort(e+1,e+ce+1); for(i=1;i<=ce;i++)if(i==1||e[i]>e[m])e[++m]=e[i]; e[++m]=inf; have[m]=1; for(i=1;i<=n;i++)have[lower_bound(e+1,e+m+1,a[i])-e]++; build(1,1,m); for(i=1;i<=q;i++){ POS++; if(op[i][0]==1){ printf("%d\n",query(op[i][1],op[i][2])); while(cp){ change(1,1,m,pool[cp][0],e[pool[cp][0]]*pool[cp][1],pool[cp][1]); cp--; } } if(op[i][0]==2)change(1,1,m,lower_bound(e+1,e+m+1,op[i][1])-e,op[i][1],1); if(op[i][0]==3)change(1,1,m,lower_bound(e+1,e+m+1,op[i][1])-e,-op[i][1],-1); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=400010,M=1111111; const ll inf=1LL<<60; int n,m,q,i,ce,have[N]; ll a[N],e[N],op[N][3]; int POS,tag[M];ll cnt[M],sum[M]; int C;ll NXT,SUM,CNT; int pool[N][3],cp; void build(int x,int a,int b){ if(a==b){ cnt[x]=have[a]; sum[x]=cnt[x]*e[a]; return; } int mid=(a+b)>>1; build(x<<1,a,mid),build(x<<1|1,mid+1,b); cnt[x]=cnt[x<<1]+cnt[x<<1|1]; sum[x]=sum[x<<1]+sum[x<<1|1]; } void change(int x,int a,int b,int c,ll A,ll B){ sum[x]+=A; cnt[x]+=B; if(a==b)return; int mid=(a+b)>>1; if(c<=mid)change(x<<1,a,mid,c,A,B);else change(x<<1|1,mid+1,b,c,A,B); } //tag=pos means zero void getnxt(int x,int a,int b){ if(NXT)return; if(tag[x]==POS)return; if(!cnt[x])return; if(a==b){ NXT=e[a]; return; } int mid=(a+b)>>1; if(C<=mid)getnxt(x<<1,a,mid); getnxt(x<<1|1,mid+1,b); } void eat(int x,int a,int b){ if(SUM>NXT)return; if(tag[x]==POS)return; if(!cnt[x])return; if(b<=C){ if(SUM+sum[x]<=NXT){ SUM+=sum[x]; CNT+=cnt[x]; tag[x]=POS; return; } if(a==b){ //o>(NXT-SUM/e[a]) ll tmp=(NXT-SUM)/e[a]; while(tmp*e[a]+SUM<=NXT)tmp++; //if(tmp>cnt[x]||tmp<1)while(1); pool[++cp][0]=a; pool[cp][1]=tmp; ll val=tmp*e[a]; for(;x;x>>=1)cnt[x]-=tmp,sum[x]-=val; SUM+=val; CNT+=tmp; return; } } int mid=(a+b)>>1; if(C>mid)eat(x<<1|1,mid+1,b); eat(x<<1,a,mid); } inline int lower(ll x){ int l=1,r=m,t,mid; while(l<=r)if(e[mid=(l+r)>>1]>=x)r=(t=mid)-1;else l=mid+1; return t; } inline int query(ll A,ll B){ int ans=0; cp=0; while(A<B){ //>=A C=lower(A); NXT=0; getnxt(1,1,m); NXT=min(NXT,B-1); C--; SUM=A; CNT=0; //SUM>NXT eat(1,1,m); if(SUM<=NXT)return -1; A=SUM; ans+=CNT; } return ans; } int main(){ scanf("%d",&n); e[ce=1]=0; for(i=1;i<=n;i++)scanf("%lld",&a[i]),e[++ce]=a[i]; scanf("%d",&q); for(i=1;i<=q;i++){ scanf("%lld%lld",&op[i][0],&op[i][1]); if(op[i][0]==1)scanf("%lld",&op[i][2]); if(op[i][0]==2)e[++ce]=op[i][1]; } sort(e+1,e+ce+1); for(i=1;i<=ce;i++)if(i==1||e[i]>e[m])e[++m]=e[i]; e[++m]=inf; have[m]=1; for(i=1;i<=n;i++)have[lower_bound(e+1,e+m+1,a[i])-e]++; build(1,1,m); for(i=1;i<=q;i++){ POS++; if(op[i][0]==1){ printf("%d\n",query(op[i][1],op[i][2])); while(cp){ change(1,1,m,pool[cp][0],e[pool[cp][0]]*pool[cp][1],pool[cp][1]); cp--; } } if(op[i][0]==2)change(1,1,m,lower_bound(e+1,e+m+1,op[i][1])-e,op[i][1],1); if(op[i][0]==3)change(1,1,m,lower_bound(e+1,e+m+1,op[i][1])-e,-op[i][1],-1); } } |