#include <cstdio>
#include <vector>
#include <algorithm>
#include <stack>
#include <tuple>
using namespace std;
#define ll long long
#define LL long long
#define PB push_back
#define MT make_tuple
#define TT tuple<int, int, long long, long long>
#define REP(x,n) for(int x = 0; x < n; x++)
vector<int> v;
vector<ll> sum;
ll heigth(int pos, TT a, int d){
ll delta = ((d - get<2>(a))*v[pos]) + get<3>(a);
return delta;
}
ll cropp(TT a, int d, int h){
ll s = (get<3>(a) - h)*(get<1>(a)-get<0>(a));
s += (d - get<2>(a))*sum[get<1>(a)]-sum[get<0>(a)];
return s;
}
void print(TT p){
printf("%d %d %lld %lld\n", get<0>(p), get<1>(p), get<2>(p), get<3>(p));
}
int binary_search(int p0, int p1, LL p2, LL p3, int d, int h){
if (p0 == p1)
return p1;
int mid = (p0+p1)/2;
if (heigth(mid, MT(p0,p1,p2,p3),d)>=h)
return binary_search(p0,mid,p2,p3,d,h);
else
return binary_search(mid+1, p1,p2,p3,d,h);
}
int main(){
int n, m;
scanf("%d%d", &n, &m);
int a;
REP(x, n){
scanf("%d", &a);
v.PB(a);
sort(v.begin(),v.end());
}
ll s = 0;
sum.PB(0);
REP(x, n){
s += v[x];
sum.PB(s);
}
//start,end,day,heigth
stack<tuple<int,int,LL,LL> >cut;
cut.push(MT(0,v.size(),0,0));
ll d, h;
// auto p = cut.top();
// printf("%d %d %lld %lld\n", get<0>(p), get<1>(p), get<2>(p), get<3>(p));
TT p;
REP(x, m){
ll rslt = 0;
scanf("%lld%lld", &d, &h);
do{
p = cut.top();
cut.pop();
rslt += cropp(p,d,h);
}
while(heigth(get<0>(p), p, d) > h && get<0>(p) != 0);
int up= binary_search(get<0>(p), get<1>(p),get<2>(p),get<3>(p),d, h);
rslt -= cropp(MT(get<0>(p), up, get<2>(p), get<3>(p)),d,h);
if (up != get<0>(p))
cut.push(MT(get<0>(p), up, get<2>(p), get<3>(p)));
if (up != get<1>(p))
cut.push(MT(up, get<1>(p), d,h));
printf("%lld\n", rslt);
}
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 | #include <cstdio> #include <vector> #include <algorithm> #include <stack> #include <tuple> using namespace std; #define ll long long #define LL long long #define PB push_back #define MT make_tuple #define TT tuple<int, int, long long, long long> #define REP(x,n) for(int x = 0; x < n; x++) vector<int> v; vector<ll> sum; ll heigth(int pos, TT a, int d){ ll delta = ((d - get<2>(a))*v[pos]) + get<3>(a); return delta; } ll cropp(TT a, int d, int h){ ll s = (get<3>(a) - h)*(get<1>(a)-get<0>(a)); s += (d - get<2>(a))*sum[get<1>(a)]-sum[get<0>(a)]; return s; } void print(TT p){ printf("%d %d %lld %lld\n", get<0>(p), get<1>(p), get<2>(p), get<3>(p)); } int binary_search(int p0, int p1, LL p2, LL p3, int d, int h){ if (p0 == p1) return p1; int mid = (p0+p1)/2; if (heigth(mid, MT(p0,p1,p2,p3),d)>=h) return binary_search(p0,mid,p2,p3,d,h); else return binary_search(mid+1, p1,p2,p3,d,h); } int main(){ int n, m; scanf("%d%d", &n, &m); int a; REP(x, n){ scanf("%d", &a); v.PB(a); sort(v.begin(),v.end()); } ll s = 0; sum.PB(0); REP(x, n){ s += v[x]; sum.PB(s); } //start,end,day,heigth stack<tuple<int,int,LL,LL> >cut; cut.push(MT(0,v.size(),0,0)); ll d, h; // auto p = cut.top(); // printf("%d %d %lld %lld\n", get<0>(p), get<1>(p), get<2>(p), get<3>(p)); TT p; REP(x, m){ ll rslt = 0; scanf("%lld%lld", &d, &h); do{ p = cut.top(); cut.pop(); rslt += cropp(p,d,h); } while(heigth(get<0>(p), p, d) > h && get<0>(p) != 0); int up= binary_search(get<0>(p), get<1>(p),get<2>(p),get<3>(p),d, h); rslt -= cropp(MT(get<0>(p), up, get<2>(p), get<3>(p)),d,h); if (up != get<0>(p)) cut.push(MT(get<0>(p), up, get<2>(p), get<3>(p))); if (up != get<1>(p)) cut.push(MT(up, get<1>(p), d,h)); printf("%lld\n", rslt); } return 0; } |
English