BZOJ4293: [PA2015]Siano
发现大小顺序不变,因为都是从0开始长,生长速度快的肯定不会落后
所以排下序,二分就可以找到一段连续的需要cov的区间
1 #include<cstdio> 2 #include<cstdlib> 3 #include<algorithm> 4 #include<cstring> 5 #define INF 0x7f7f7f7f 6 #define MAXN 500010 7 #define rint register int 8 #define ll long long 9 using namespace std; 10 ll read(){ 11 ll x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 #define lc k<<1 17 #define rc k<<1|1 18 struct SegmentTree{ 19 struct Node{ 20 ll mn,mt; 21 ll sn,st; 22 ll tg,tgt; 23 int L,R; 24 }st[MAXN<<2]; 25 ll a[MAXN],s[MAXN]; 26 ll T; 27 int n; 28 Node Merge(Node A,Node B){ 29 Node r; 30 r.L=A.L,r.R=B.R; 31 r.mn=B.mn,r.mt=B.mt; 32 r.sn=A.sn+(T-A.st)*(s[A.R]-s[A.L-1])+B.sn+(T-B.st)*(s[B.R]-s[B.L-1]); 33 r.st=T; 34 r.tg=0LL,r.tgt=0LL; 35 return r; 36 } 37 void workcov(int k,ll v,ll t){ 38 int L=st[k].L,R=st[k].R; 39 st[k].mn=v,st[k].mt=t; 40 st[k].sn=v*(R-L+1),st[k].st=t; 41 st[k].tg=v,st[k].tgt=t; 42 } 43 void pushdown(int k){ 44 if(st[k].tgt){ 45 for(rint i=0;i<=1;i++){ 46 int c=k<<1|i; 47 if(st[c].tgt<st[k].tgt)workcov(c,st[k].tg,st[k].tgt); 48 } 49 st[k].tg=0LL; 50 st[k].tgt=0LL; 51 } 52 } 53 ll query(int k,int a,int b,ll v){ 54 int L=st[k].L,R=st[k].R; 55 ll r=0LL; 56 if(a<=L&&R<=b){ 57 r=st[k].sn+(T-st[k].st)*(s[R]-s[L-1]); 58 workcov(k,v,T); 59 } 60 else{ 61 int mid=(L+R)>>1; 62 pushdown(k); 63 if(a<=mid)r+=query(lc,a,b,v); 64 if(b>mid)r+=query(rc,a,b,v); 65 st[k]=Merge(st[lc],st[rc]); 66 } 67 return r; 68 } 69 int getp(int k,ll v){ 70 int L=st[k].L,R=st[k].R; 71 if(L==R){ 72 if(st[k].mn+(T-st[k].mt)*a[L]>=v)return L; 73 else return L+1; 74 } 75 pushdown(k); 76 if(st[lc].mn+(T-st[lc].mt)*a[st[lc].R]>=v){ 77 return getp(lc,v); 78 } 79 else{ 80 return getp(rc,v); 81 } 82 } 83 void build(int k,int L,int R){ 84 st[k].L=L,st[k].R=R; 85 if(L==R){ 86 st[k].mn=0LL,st[k].mt=0LL; 87 st[k].sn=0LL,st[k].st=0LL; 88 st[k].tgt=0LL; 89 } 90 else{ 91 int mid=(L+R)>>1; 92 build(lc,L,mid); 93 build(rc,mid+1,R); 94 st[k]=Merge(st[lc],st[rc]); 95 } 96 } 97 ll ask(ll v,ll t){ 98 T=t; 99 int p=getp(1,v); 100 if(p<=n)return query(1,p,n,v)-(n-p+1)*v; 101 else return 0LL; 102 } 103 }ST; 104 int n; 105 int main() 106 { 107 // freopen("data.in","r",stdin); 108 int T; 109 n=read(),T=read();ST.n=n; 110 for(rint i=1;i<=n;i++)ST.a[i]=read(); 111 sort(ST.a+1,ST.a+n+1); 112 for(rint i=1;i<=n;i++)ST.s[i]=ST.s[i-1]+ST.a[i]; 113 ST.build(1,1,n); 114 ll t,v,ans; 115 while(T--){ 116 t=read(),v=read(); 117 ans=ST.ask(v,t); 118 printf("%lld\n",ans); 119 } 120 return 0; 121 }