#include <iostream> #include <algorithm> #include <set> using namespace std; unsigned long long n, m; unsigned long long trawa[500001]; unsigned long long sumaTraw[500001]; unsigned d, h; class Grupa{ public: unsigned long long min, max, day, h; Grupa(unsigned long long argMin, unsigned long long argMax, unsigned long long argDay, unsigned long long argH): min(argMin), max(argMax), day(argDay), h(argH){ } }; struct classcomp { bool operator() (const Grupa & lhs, const Grupa & rhs) const { return lhs.min < rhs.min; } }; typedef set <Grupa, classcomp> mySet; typedef mySet::iterator myIterator; mySet grupy; Grupa targetG(0,0,0,0); void find_group(unsigned long long x){ targetG.min = x; myIterator it = grupy.upper_bound(targetG); --it; targetG = *it; } bool is_cutted(unsigned long long x){ find_group(x); unsigned long long liczbaDni = (d-targetG.day); unsigned long long wysokosc = liczbaDni * trawa[x] + targetG.h; return wysokosc>h; } unsigned long long find_lowest_cutting_index(unsigned long long bottom, unsigned long long top){ if(bottom == top){ if(is_cutted(bottom)){ return bottom; }else return n; } unsigned mid = (bottom + top) >> 1; if(is_cutted(mid)){ return find_lowest_cutting_index(bottom, mid); } else{ return find_lowest_cutting_index(mid+1, top); } } unsigned long long count_hair(unsigned min, unsigned max, unsigned day, unsigned height){ unsigned long long cut = sumaTraw[max] - sumaTraw[min] + trawa[min]; cut *= (d - day); cut += height * (max - min + 1); cut -= h * (max - min + 1); return cut; } unsigned long long chop_groups(unsigned long long x){ unsigned long long zgolone = 0; myIterator it = grupy.upper_bound(targetG); --it; myIterator it2 = it; zgolone = count_hair(x,it2->max,it2->day,it2->h); ++it2; while(it2!=grupy.end()){ zgolone += count_hair(it2->min,it2->max,it2->day,it2->h); ++it2; } targetG = *it; grupy.erase(it,grupy.end()); if(targetG.min<x){ Grupa g(targetG.min,x-1,targetG.day,targetG.h); grupy.insert(g); } targetG.min=x; targetG.max=n-1; targetG.h = h; targetG.day = d; grupy.insert(targetG); return zgolone; } int main () { ios_base::sync_with_stdio(0); cin >> n >> m; for(unsigned long long i = 0;i<n;++i) cin >> trawa[i]; sort(trawa,trawa+n); sumaTraw[0] = trawa[0]; for(unsigned long long i = 1;i<n;++i) sumaTraw[i] = trawa[i] + sumaTraw[i-1]; Grupa g (0,n-1,0,0); grupy.insert(g); for(unsigned long long i = 0;i<m;++i){ cin >> d >> h; unsigned long long x = find_lowest_cutting_index(0,n-1); if(x == n){ cout << "0\n"; continue; } cout << chop_groups(x) << "\n"; } 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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include <iostream> #include <algorithm> #include <set> using namespace std; unsigned long long n, m; unsigned long long trawa[500001]; unsigned long long sumaTraw[500001]; unsigned d, h; class Grupa{ public: unsigned long long min, max, day, h; Grupa(unsigned long long argMin, unsigned long long argMax, unsigned long long argDay, unsigned long long argH): min(argMin), max(argMax), day(argDay), h(argH){ } }; struct classcomp { bool operator() (const Grupa & lhs, const Grupa & rhs) const { return lhs.min < rhs.min; } }; typedef set <Grupa, classcomp> mySet; typedef mySet::iterator myIterator; mySet grupy; Grupa targetG(0,0,0,0); void find_group(unsigned long long x){ targetG.min = x; myIterator it = grupy.upper_bound(targetG); --it; targetG = *it; } bool is_cutted(unsigned long long x){ find_group(x); unsigned long long liczbaDni = (d-targetG.day); unsigned long long wysokosc = liczbaDni * trawa[x] + targetG.h; return wysokosc>h; } unsigned long long find_lowest_cutting_index(unsigned long long bottom, unsigned long long top){ if(bottom == top){ if(is_cutted(bottom)){ return bottom; }else return n; } unsigned mid = (bottom + top) >> 1; if(is_cutted(mid)){ return find_lowest_cutting_index(bottom, mid); } else{ return find_lowest_cutting_index(mid+1, top); } } unsigned long long count_hair(unsigned min, unsigned max, unsigned day, unsigned height){ unsigned long long cut = sumaTraw[max] - sumaTraw[min] + trawa[min]; cut *= (d - day); cut += height * (max - min + 1); cut -= h * (max - min + 1); return cut; } unsigned long long chop_groups(unsigned long long x){ unsigned long long zgolone = 0; myIterator it = grupy.upper_bound(targetG); --it; myIterator it2 = it; zgolone = count_hair(x,it2->max,it2->day,it2->h); ++it2; while(it2!=grupy.end()){ zgolone += count_hair(it2->min,it2->max,it2->day,it2->h); ++it2; } targetG = *it; grupy.erase(it,grupy.end()); if(targetG.min<x){ Grupa g(targetG.min,x-1,targetG.day,targetG.h); grupy.insert(g); } targetG.min=x; targetG.max=n-1; targetG.h = h; targetG.day = d; grupy.insert(targetG); return zgolone; } int main () { ios_base::sync_with_stdio(0); cin >> n >> m; for(unsigned long long i = 0;i<n;++i) cin >> trawa[i]; sort(trawa,trawa+n); sumaTraw[0] = trawa[0]; for(unsigned long long i = 1;i<n;++i) sumaTraw[i] = trawa[i] + sumaTraw[i-1]; Grupa g (0,n-1,0,0); grupy.insert(g); for(unsigned long long i = 0;i<m;++i){ cin >> d >> h; unsigned long long x = find_lowest_cutting_index(0,n-1); if(x == n){ cout << "0\n"; continue; } cout << chop_groups(x) << "\n"; } return 0; } |