#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxN = 2e5 + 10;
struct Client {
int x, lvl;
void get() {
scanf("%lld", &x);
lvl = 1;
}
} t[maxN];
int find(int);
struct Colision {
int i, lvl, tim;
Colision(int i, int tim)
: i(i), lvl(t[i].lvl), tim(tim) {
// printf("Will colide %lld<%lld> with %lld at time %lld\n", i, lvl, find(i+1), tim);
}
bool operator<(Colision const& o) const {
return tim > o.tim;
}
};
int predict(Client const& a, Client const& b) {
return (b.x - a.x + a.lvl - 1) / a.lvl;
}
int FU[maxN];
int find(int x) { return x == FU[x] ? x : FU[x] = find(FU[x]); }
int n, q;
struct Situation {
int tim, con, lost, lost_lvl;
Situation(int tim, int c, int lost, int lost_lvl)
: tim(tim), con(c), lost(lost), lost_lvl(lost_lvl) {}
};
vector<Situation> situations;
void ask() {
int a = -1, b = situations.size(), avg, tim;
scanf("%lld", &tim);
while(b - a > 1) {
avg = (a + b) / 2;
if(situations[avg].tim <= tim) a = avg;
else b = avg;
}
Situation const& s = situations[a];
printf("%lld\n", s.lost + s.lost_lvl * (tim - s.tim));
}
#undef int
int main() {
#define int long long
scanf("%lld%lld", &n, &q);
t[0].lvl = 1;
t[0].x = 0;
for(int i = 1; i <= n; ++i) {
t[i].get();
FU[i] = i;
}
FU[n + 1] = n + 1;
priority_queue<Colision> col;
for(int i = 0; i < n; ++i)
col.emplace(i, predict(t[i], t[i+1]));
situations.emplace_back(0, n + 1, 0, 0);
while(!col.empty()) {
Colision c = col.top();
col.pop();
if(t[c.i].lvl != c.lvl || find(c.i) != c.i)
continue;
int j = find(c.i + 1);
int lost_lvl = situations.back().lost_lvl;
int add_lost = (t[c.i].lvl * c.tim - t[j].x + t[c.i].x) * t[j].lvl;
lost_lvl -= t[c.i].lvl * (t[c.i].lvl - 1) / 2;
lost_lvl -= t[j].lvl * (t[j].lvl - 1) / 2;
t[c.i].lvl += t[j].lvl;
lost_lvl += t[c.i].lvl * (t[c.i].lvl - 1) / 2;
FU[j] = j + 1;
// printf("COLIDE %lld<%lld> with %lld at time %lld\n", c.i, c.lvl, j, c.tim);
// printf("add_lost = %lld\n", add_lost);
Situation const& s = situations.back();
situations.emplace_back(c.tim, s.con - 1, (c.tim - s.tim) * s.lost_lvl + s.lost + add_lost, lost_lvl);
if(find(c.i + 1) != n + 1)
col.emplace(c.i, predict(t[c.i], t[find(c.i + 1)]));
}
for(int i = 0; i < q; ++i) ask();
}
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 | #include <bits/stdc++.h> using namespace std; #define int long long const int maxN = 2e5 + 10; struct Client { int x, lvl; void get() { scanf("%lld", &x); lvl = 1; } } t[maxN]; int find(int); struct Colision { int i, lvl, tim; Colision(int i, int tim) : i(i), lvl(t[i].lvl), tim(tim) { // printf("Will colide %lld<%lld> with %lld at time %lld\n", i, lvl, find(i+1), tim); } bool operator<(Colision const& o) const { return tim > o.tim; } }; int predict(Client const& a, Client const& b) { return (b.x - a.x + a.lvl - 1) / a.lvl; } int FU[maxN]; int find(int x) { return x == FU[x] ? x : FU[x] = find(FU[x]); } int n, q; struct Situation { int tim, con, lost, lost_lvl; Situation(int tim, int c, int lost, int lost_lvl) : tim(tim), con(c), lost(lost), lost_lvl(lost_lvl) {} }; vector<Situation> situations; void ask() { int a = -1, b = situations.size(), avg, tim; scanf("%lld", &tim); while(b - a > 1) { avg = (a + b) / 2; if(situations[avg].tim <= tim) a = avg; else b = avg; } Situation const& s = situations[a]; printf("%lld\n", s.lost + s.lost_lvl * (tim - s.tim)); } #undef int int main() { #define int long long scanf("%lld%lld", &n, &q); t[0].lvl = 1; t[0].x = 0; for(int i = 1; i <= n; ++i) { t[i].get(); FU[i] = i; } FU[n + 1] = n + 1; priority_queue<Colision> col; for(int i = 0; i < n; ++i) col.emplace(i, predict(t[i], t[i+1])); situations.emplace_back(0, n + 1, 0, 0); while(!col.empty()) { Colision c = col.top(); col.pop(); if(t[c.i].lvl != c.lvl || find(c.i) != c.i) continue; int j = find(c.i + 1); int lost_lvl = situations.back().lost_lvl; int add_lost = (t[c.i].lvl * c.tim - t[j].x + t[c.i].x) * t[j].lvl; lost_lvl -= t[c.i].lvl * (t[c.i].lvl - 1) / 2; lost_lvl -= t[j].lvl * (t[j].lvl - 1) / 2; t[c.i].lvl += t[j].lvl; lost_lvl += t[c.i].lvl * (t[c.i].lvl - 1) / 2; FU[j] = j + 1; // printf("COLIDE %lld<%lld> with %lld at time %lld\n", c.i, c.lvl, j, c.tim); // printf("add_lost = %lld\n", add_lost); Situation const& s = situations.back(); situations.emplace_back(c.tim, s.con - 1, (c.tim - s.tim) * s.lost_lvl + s.lost + add_lost, lost_lvl); if(find(c.i + 1) != n + 1) col.emplace(c.i, predict(t[c.i], t[find(c.i + 1)])); } for(int i = 0; i < q; ++i) ask(); } |
English