#include <bits/stdc++.h> using namespace std; const int MAXN = 1e5*2+69; const int MAXM = 1e6+69; #define pr if(0) int p[MAXN], p_[MAXN]; int ilosc[MAXN]; struct F { int l, p, v; } f[MAXN]; int gp(int x) { if (f[x].p == x) return x; return f[x].p = gp(f[x].p); } map<long long int, vector<int>> l; long long int cojeden = 0; long long int w_[MAXM], in[MAXM], w, wo, ctm; int cp; inline long long int sum(long long int a) { return a * (a-1) / 2; } int n, m; void join(int a, int b) { pr printf("%d :: %d\n", a, b); b=gp(b); a=gp(a); // a >= b assert(a >= b); if (a==b) { pr printf("\tattemt to merge %d with itself\n", a); return; } long long int right = in[f[b].l] + (f[b].v-1)*ctm; long long int wdiff = (in[f[a].l] - ctm - right) * f[a].v; pr printf("\tmerge %d to %d, cojeden = cojeden - %lld - %lld + %lld = %lld\n", a, b, sum(f[b].v), sum(f[a].v), sum(f[b].v+f[a].v), cojeden - sum(f[b].v) - sum(f[a].v) + sum(f[b].v+f[a].v)); w -= wdiff; pr printf("\tw -= %lld = =%lld\n", wdiff, w); cojeden += sum(f[a].v + f[b].v) - sum(f[a].v) - sum(f[b].v); f[a].v = f[a].v + f[b].v; f[b].v = f[a].v; f[a].l = min(f[a].l, f[b].l); f[a].p = max(f[a].p, f[b].p); f[b].l = f[a].l; f[b].p = f[a].p; if (f[a].p == n) return; long long int index = (in[f[a].p+1] - in[f[a].l] - 1) / f[a].v + 1; pr printf("\tl[%lld] += %d\n", index, a+1); l[index].push_back(a+1); } int main() { scanf("%d%d", &n, &m); long long int prev = 0, cur = 0; // guard l[1e12].push_back(0); f[0] = {0,0,1}; for (int i = 1; i <= n; i++) { scanf("%lld", in+i); pr printf("%d -> [%lld] %lld\n", i, in[i], in[i]-prev); l[in[i]-prev].push_back(i); prev=in[i]; f[i] = {i, i, 1}; } for (int i = 0; i < m; i++) { scanf("%d", p+i); p_[i] = p[i]; } sort(p, p+m); prev = 0; for (cp = 0; cp < m; cp++) { pr printf("piekarnik %d\n", p[cp]); while (l.size()) { long long int co = l.begin()->first; if (co > p[cp]) break; vector<int> &v = l.begin()->second; ctm = co; w += cojeden * (ctm-prev); w_[co] = w; pr printf("\tpodbija czas do %lld, w += %lld = %lld\n", co, cojeden * (co-prev), w); for (int it = 0; it < v.size(); it++) { join(v[it], v[it]-1); } prev = co; l.erase(l.begin()); } w += cojeden * (p[cp]-prev); pr printf("podbija czas do %lld, w += %lld = %lld\n", p[cp], cojeden * (p[cp] - prev), w); w_[p[cp]] = w; w -= wo; wo = 0; prev = p[cp]; } for (int i = 0; i < m; i++) { printf("%lld\n", w_[p_[i]]); } }
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 | #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5*2+69; const int MAXM = 1e6+69; #define pr if(0) int p[MAXN], p_[MAXN]; int ilosc[MAXN]; struct F { int l, p, v; } f[MAXN]; int gp(int x) { if (f[x].p == x) return x; return f[x].p = gp(f[x].p); } map<long long int, vector<int>> l; long long int cojeden = 0; long long int w_[MAXM], in[MAXM], w, wo, ctm; int cp; inline long long int sum(long long int a) { return a * (a-1) / 2; } int n, m; void join(int a, int b) { pr printf("%d :: %d\n", a, b); b=gp(b); a=gp(a); // a >= b assert(a >= b); if (a==b) { pr printf("\tattemt to merge %d with itself\n", a); return; } long long int right = in[f[b].l] + (f[b].v-1)*ctm; long long int wdiff = (in[f[a].l] - ctm - right) * f[a].v; pr printf("\tmerge %d to %d, cojeden = cojeden - %lld - %lld + %lld = %lld\n", a, b, sum(f[b].v), sum(f[a].v), sum(f[b].v+f[a].v), cojeden - sum(f[b].v) - sum(f[a].v) + sum(f[b].v+f[a].v)); w -= wdiff; pr printf("\tw -= %lld = =%lld\n", wdiff, w); cojeden += sum(f[a].v + f[b].v) - sum(f[a].v) - sum(f[b].v); f[a].v = f[a].v + f[b].v; f[b].v = f[a].v; f[a].l = min(f[a].l, f[b].l); f[a].p = max(f[a].p, f[b].p); f[b].l = f[a].l; f[b].p = f[a].p; if (f[a].p == n) return; long long int index = (in[f[a].p+1] - in[f[a].l] - 1) / f[a].v + 1; pr printf("\tl[%lld] += %d\n", index, a+1); l[index].push_back(a+1); } int main() { scanf("%d%d", &n, &m); long long int prev = 0, cur = 0; // guard l[1e12].push_back(0); f[0] = {0,0,1}; for (int i = 1; i <= n; i++) { scanf("%lld", in+i); pr printf("%d -> [%lld] %lld\n", i, in[i], in[i]-prev); l[in[i]-prev].push_back(i); prev=in[i]; f[i] = {i, i, 1}; } for (int i = 0; i < m; i++) { scanf("%d", p+i); p_[i] = p[i]; } sort(p, p+m); prev = 0; for (cp = 0; cp < m; cp++) { pr printf("piekarnik %d\n", p[cp]); while (l.size()) { long long int co = l.begin()->first; if (co > p[cp]) break; vector<int> &v = l.begin()->second; ctm = co; w += cojeden * (ctm-prev); w_[co] = w; pr printf("\tpodbija czas do %lld, w += %lld = %lld\n", co, cojeden * (co-prev), w); for (int it = 0; it < v.size(); it++) { join(v[it], v[it]-1); } prev = co; l.erase(l.begin()); } w += cojeden * (p[cp]-prev); pr printf("podbija czas do %lld, w += %lld = %lld\n", p[cp], cojeden * (p[cp] - prev), w); w_[p[cp]] = w; w -= wo; wo = 0; prev = p[cp]; } for (int i = 0; i < m; i++) { printf("%lld\n", w_[p_[i]]); } } |