//Aleksander Łukasiewicz
#include<bits/stdc++.h>
using namespace std;
#define fru(j,n) for(int j=0; j<(n); ++j)
#define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it)
#define x first
#define y second
#define pb push_back
#define mp make_pair
#define ALL(G) (G).begin(),(G).end()
typedef long long LL;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int INF = 1000000009;
const int MAXN = 500000;
int n;
int tab[MAXN + 3];
LL suf[MAXN + 3];
stack< pair<int, pair<LL,LL> > > cuts;
inline LL interval(int a, int b){
return suf[a] - suf[b+1];
}
inline LL grow(int ind, LL time, LL add){
return add + time*tab[ind];
}
int binsearch(int beg, int end, LL height, LL time, LL add){
while(beg + 1 < end){
int mid = (beg + end)/2;
if(grow(mid, time, add) > height)
end = mid;
else
beg = mid;
}
return end;
}
int main(){
int Q;
scanf("%d %d", &n, &Q);
for(int i=0; i<n; i++)
scanf("%d", &tab[i]);
sort(tab, tab+n);
for(int i=n-1; i>=0; i--)
suf[i] = suf[i+1] + tab[i];
cuts.push(mp(0, mp(0,0)));
while(Q--){
LL d, h;
scanf("%lld %lld", &d, &h);
LL ans = 0;
int prev = n;
while(!cuts.empty()){
int ind = cuts.top().x;
LL cuttime = cuts.top().y.x;
LL cutheight = cuts.top().y.y;
if(grow(ind, d-cuttime, cutheight) < h)
break;
ans += interval(ind, prev-1)*(d-cuttime) + (cutheight - h)*(prev-ind);
cuts.pop();
prev = ind;
}
int ind; LL cuttime, cutheight;
if(cuts.empty())
cuttime = cutheight = ind = 0;
else
ind = cuts.top().x, cuttime = cuts.top().y.x, cutheight = cuts.top().y.y;
int cutplace = binsearch(ind-1, prev, h, d-cuttime, cutheight);
ans += interval(cutplace, prev-1)*(d-cuttime) + (cutheight - h)*(prev - cutplace);
if(cutplace < n)
cuts.push(mp(cutplace, mp(d, h)));
printf("%lld\n", ans);
}
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 | //Aleksander Łukasiewicz #include<bits/stdc++.h> using namespace std; #define fru(j,n) for(int j=0; j<(n); ++j) #define tr(it,v) for(typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it) #define x first #define y second #define pb push_back #define mp make_pair #define ALL(G) (G).begin(),(G).end() typedef long long LL; typedef pair<int,int> PII; typedef vector<int> VI; const int INF = 1000000009; const int MAXN = 500000; int n; int tab[MAXN + 3]; LL suf[MAXN + 3]; stack< pair<int, pair<LL,LL> > > cuts; inline LL interval(int a, int b){ return suf[a] - suf[b+1]; } inline LL grow(int ind, LL time, LL add){ return add + time*tab[ind]; } int binsearch(int beg, int end, LL height, LL time, LL add){ while(beg + 1 < end){ int mid = (beg + end)/2; if(grow(mid, time, add) > height) end = mid; else beg = mid; } return end; } int main(){ int Q; scanf("%d %d", &n, &Q); for(int i=0; i<n; i++) scanf("%d", &tab[i]); sort(tab, tab+n); for(int i=n-1; i>=0; i--) suf[i] = suf[i+1] + tab[i]; cuts.push(mp(0, mp(0,0))); while(Q--){ LL d, h; scanf("%lld %lld", &d, &h); LL ans = 0; int prev = n; while(!cuts.empty()){ int ind = cuts.top().x; LL cuttime = cuts.top().y.x; LL cutheight = cuts.top().y.y; if(grow(ind, d-cuttime, cutheight) < h) break; ans += interval(ind, prev-1)*(d-cuttime) + (cutheight - h)*(prev-ind); cuts.pop(); prev = ind; } int ind; LL cuttime, cutheight; if(cuts.empty()) cuttime = cutheight = ind = 0; else ind = cuts.top().x, cuttime = cuts.top().y.x, cutheight = cuts.top().y.y; int cutplace = binsearch(ind-1, prev, h, d-cuttime, cutheight); ans += interval(cutplace, prev-1)*(d-cuttime) + (cutheight - h)*(prev - cutplace); if(cutplace < n) cuts.push(mp(cutplace, mp(d, h))); printf("%lld\n", ans); } return 0; } |
English