#include<cstdio>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=500000;
int a[N+1];
long long pref[N+2]; // pref[i]=a[0]+...+a[i-1]
struct block {
long long d;
long long b;
long long s; // początek bloku b
block(int dd, int bb, int ss) : d(dd), b(bb), s(ss) {}
};
vector<block> field;
long long intSum(int i, int j) {
//suma el. a od i do j-1
return pref[j]-pref[i];
}
int findIndex(int i,int j,long long d_coef,long long b_coef,long long b) {
while(i + 1 < j) {
int middle=(i+j)/2;
if(a[middle]*d_coef+b_coef <= b ) i=middle;
else j=middle;
}
return i;
}
long long harvest(long long b, int n) {
int j=field.size()-2; // gwarantujemy ze field.size() >=2
long long d_coef=0;
long long cut=0;
long long b_coef;
while(true) {
d_coef+=field[j+1].d;
b_coef=field[j].b;
if(a[field[j].s]*d_coef+b_coef <= b) break;
cut+=d_coef*intSum(field[j].s,field[j+1].s)
+b_coef*(field[j+1].s-field[j].s);
field.pop_back();
--j;
}
// k - ostatni indeks gdzie trawa[i] <= b
int k=findIndex(field[j].s,field[j+1].s,d_coef,b_coef,b);
++k; // odtąd tniemy
cut+=d_coef*intSum(k,field[j+1].s)+b_coef*(field[j+1].s-k);
field[j+1].b=b;
field[j+1].d=d_coef;
field[j+1].s=k;
cut-=(n-k)*b; // tniemy do wys. b
return cut;
}
int main() {
int n,m;
scanf("%d",&n); ++n;
scanf("%d",&m);
a[0]=0; // wartownik
for(int i=1; i<n; ++i) scanf("%d",a+i);
sort(a,a+n);
pref[0]=0;
for (int i=0; i<n; ++i) pref[i+1]=pref[i]+a[i];
long long d_prev=0;
field.push_back(block(0,0,0)); //wartownik
for (int i=0; i<m; ++i) {
long long b,d;
scanf("%lld",&d);
scanf("%lld",&b);
if((d-d_prev)*a[n-1]+field.back().b > b) {
field.push_back(block(d-d_prev,0,n));
long long cut = harvest(b,n);
d_prev=d;
printf("%lld\n",cut);
}
else printf("%d\n",0);
}
return 0;
}
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 | #include<cstdio> #include<vector> #include<algorithm> #include<iostream> using namespace std; const int N=500000; int a[N+1]; long long pref[N+2]; // pref[i]=a[0]+...+a[i-1] struct block { long long d; long long b; long long s; // początek bloku b block(int dd, int bb, int ss) : d(dd), b(bb), s(ss) {} }; vector<block> field; long long intSum(int i, int j) { //suma el. a od i do j-1 return pref[j]-pref[i]; } int findIndex(int i,int j,long long d_coef,long long b_coef,long long b) { while(i + 1 < j) { int middle=(i+j)/2; if(a[middle]*d_coef+b_coef <= b ) i=middle; else j=middle; } return i; } long long harvest(long long b, int n) { int j=field.size()-2; // gwarantujemy ze field.size() >=2 long long d_coef=0; long long cut=0; long long b_coef; while(true) { d_coef+=field[j+1].d; b_coef=field[j].b; if(a[field[j].s]*d_coef+b_coef <= b) break; cut+=d_coef*intSum(field[j].s,field[j+1].s) +b_coef*(field[j+1].s-field[j].s); field.pop_back(); --j; } // k - ostatni indeks gdzie trawa[i] <= b int k=findIndex(field[j].s,field[j+1].s,d_coef,b_coef,b); ++k; // odtąd tniemy cut+=d_coef*intSum(k,field[j+1].s)+b_coef*(field[j+1].s-k); field[j+1].b=b; field[j+1].d=d_coef; field[j+1].s=k; cut-=(n-k)*b; // tniemy do wys. b return cut; } int main() { int n,m; scanf("%d",&n); ++n; scanf("%d",&m); a[0]=0; // wartownik for(int i=1; i<n; ++i) scanf("%d",a+i); sort(a,a+n); pref[0]=0; for (int i=0; i<n; ++i) pref[i+1]=pref[i]+a[i]; long long d_prev=0; field.push_back(block(0,0,0)); //wartownik for (int i=0; i<m; ++i) { long long b,d; scanf("%lld",&d); scanf("%lld",&b); if((d-d_prev)*a[n-1]+field.back().b > b) { field.push_back(block(d-d_prev,0,n)); long long cut = harvest(b,n); d_prev=d; printf("%lld\n",cut); } else printf("%d\n",0); } return 0; } |
English