#include <stdio.h> #include <vector> #include <algorithm> //typedef std::pair<int, int> IntPair; //typedef std::pair<IntPair, int > Cut; typedef struct _Cut{ long long int p; long long int h; long long int d; } Cut; int main(){ long long int g, k; long long int d, w; scanf("%lld %lld", &g, &k); std::vector<long long int> pole(g, 0); std::vector<long long int> grow(g + 1, 0); for (int i = 0; i < g; i++) scanf("%lld", &pole[i]); std::sort(pole.begin(), pole.end()); grow[g - 1] = pole[g - 1]; for (int i = g - 2; i >= 0; i--) grow[i] = grow[i + 1] + pole[i]; /* for (int i = 0; i < g; i++) printf("%d ", pole[i]); printf("\n"); for (int i = 0; i < g; i++) printf("%lld ", grow[i]); printf("\n");*/ std::vector<Cut> cuts; cuts.push_back(Cut{0, 0, 0}); long long int acc; long long int tmpCut; for (int i = 0; i < k; i++){ scanf("%lld %lld", &d, &w); //printf("CIECIE %d %d\n",d,w); acc = 0; long long int lastPos = g; while (!cuts.empty()){ long long int growDays = d - cuts.back().d; if (cuts.back().h + growDays * pole[cuts.back().p] >= w){//czyli poczatek klocka juz urosl ponad miare tmpCut = (growDays * (grow[cuts.back().p] - grow[lastPos]) + (cuts.back().h - w) * (lastPos - cuts.back().p));//TODO dodac warunek brzegowy //printf("obciety klocek h %d d %d p %d wartosc %lld\n", cuts.back().h, cuts.back().d, cuts.back().p, tmpCut); acc += tmpCut; lastPos = cuts.back().p; //tak by dotykac tylkonowego przedizalu cuts.pop_back(); if (cuts.empty()) { cuts.push_back(Cut{ 0, w, d });//dojechal do 0 break; } } else { //binary search long long int h = cuts.back().h; long long int p = cuts.back().p; long long int k = lastPos - 1;// g ? g - 1 : lastPos; while (p < k){ //int m = ceil((float)(p + k) / 2.0); long long int m = (p + k) / 2; //printf("BINARY %d %d %d %d (%d %d)\n", w, h, growDays, pole[m],p,k); if (w > h + growDays * pole[m]){ p = m + 1; } else { k = m ; } } tmpCut = (growDays * (grow[p] - grow[lastPos]) - (lastPos - p) * (w - h) );//to co uroslo nad ale minus nasza wysokosc acc += tmpCut; //printf("pozycja ciecia klocka %d wartosc %lld\n", p, tmpCut); cuts.push_back(Cut{ p, w, d }); break; } } /*printf("=====================\n"); for (int j = 0; j < (int)cuts.size(); j++) printf("pozycja %d wysokosc %d dzien %d\n", cuts[j].p, cuts[j].h, cuts[j].d); printf("=====%lld\n",acc);*/ printf("%lld\n", acc); } 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 | #include <stdio.h> #include <vector> #include <algorithm> //typedef std::pair<int, int> IntPair; //typedef std::pair<IntPair, int > Cut; typedef struct _Cut{ long long int p; long long int h; long long int d; } Cut; int main(){ long long int g, k; long long int d, w; scanf("%lld %lld", &g, &k); std::vector<long long int> pole(g, 0); std::vector<long long int> grow(g + 1, 0); for (int i = 0; i < g; i++) scanf("%lld", &pole[i]); std::sort(pole.begin(), pole.end()); grow[g - 1] = pole[g - 1]; for (int i = g - 2; i >= 0; i--) grow[i] = grow[i + 1] + pole[i]; /* for (int i = 0; i < g; i++) printf("%d ", pole[i]); printf("\n"); for (int i = 0; i < g; i++) printf("%lld ", grow[i]); printf("\n");*/ std::vector<Cut> cuts; cuts.push_back(Cut{0, 0, 0}); long long int acc; long long int tmpCut; for (int i = 0; i < k; i++){ scanf("%lld %lld", &d, &w); //printf("CIECIE %d %d\n",d,w); acc = 0; long long int lastPos = g; while (!cuts.empty()){ long long int growDays = d - cuts.back().d; if (cuts.back().h + growDays * pole[cuts.back().p] >= w){//czyli poczatek klocka juz urosl ponad miare tmpCut = (growDays * (grow[cuts.back().p] - grow[lastPos]) + (cuts.back().h - w) * (lastPos - cuts.back().p));//TODO dodac warunek brzegowy //printf("obciety klocek h %d d %d p %d wartosc %lld\n", cuts.back().h, cuts.back().d, cuts.back().p, tmpCut); acc += tmpCut; lastPos = cuts.back().p; //tak by dotykac tylkonowego przedizalu cuts.pop_back(); if (cuts.empty()) { cuts.push_back(Cut{ 0, w, d });//dojechal do 0 break; } } else { //binary search long long int h = cuts.back().h; long long int p = cuts.back().p; long long int k = lastPos - 1;// g ? g - 1 : lastPos; while (p < k){ //int m = ceil((float)(p + k) / 2.0); long long int m = (p + k) / 2; //printf("BINARY %d %d %d %d (%d %d)\n", w, h, growDays, pole[m],p,k); if (w > h + growDays * pole[m]){ p = m + 1; } else { k = m ; } } tmpCut = (growDays * (grow[p] - grow[lastPos]) - (lastPos - p) * (w - h) );//to co uroslo nad ale minus nasza wysokosc acc += tmpCut; //printf("pozycja ciecia klocka %d wartosc %lld\n", p, tmpCut); cuts.push_back(Cut{ p, w, d }); break; } } /*printf("=====================\n"); for (int j = 0; j < (int)cuts.size(); j++) printf("pozycja %d wysokosc %d dzien %d\n", cuts[j].p, cuts[j].h, cuts[j].d); printf("=====%lld\n",acc);*/ printf("%lld\n", acc); } return 0; } |