#include <iostream>
#include <algorithm>
#include <assert.h>
#include <queue>
#define mp make_pair
using namespace std;
long long czas[300001];
int ojc[300001];
int roz[300001];
int mn[300001];
int find(int poz)
{
if(ojc[poz]==-1) return poz;
ojc[poz]=find(ojc[poz]);
return ojc[poz];
}
void merge(int a, int b)
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
{
if(roz[fa]<roz[fb])
{
fa^=fb;
fb^=fa;
fa^=fb;
}
roz[fa]+=roz[fb];
ojc[fb]=fa;
mn[fa]=min(mn[fa], mn[fb]);
}
}
long long pre[2000001];
long long dod[2000001];
int main()
{
long long n, m;
scanf("%lld%lld", &n, &m);
for(int i=0; i<=n; i++) ojc[i]=-1;
for(int i=0; i<=n; i++) roz[i]=1;
for(int i=0; i<=n; i++) mn[i]=i;
for(int i=1; i<=n; i++) scanf("%lld", &czas[i]);
czas[n+1]=1e18;
priority_queue <pair <long long, int>, vector <pair <long long, int> >, greater<pair <long long, int> > > kol;
for(int i=1; i<=n; i++)
{
kol.push(mp(czas[i]-czas[i-1], i-1));
}
while(!kol.empty())
{
pair <long long, int> akt=kol.top();
kol.pop();
if(akt.first>1000000) break;
int f1=find(akt.second);
int f2=find(akt.second+1);
if(f1!=f2)
{
long long r1=roz[f1], r2=roz[f2];
pre[akt.first+1]-=r1*(r1-1)/2;
pre[akt.first+1]-=r2*(r2-1)/2;
merge(f1, f2);
int nf=find(f1);
long long nr=roz[nf];
int pier=mn[nf];
assert(nr==r1+r2);
pre[akt.first+1]+=nr*(nr-1)/2;
dod[akt.first]+=(akt.first*r1-(czas[akt.second+1]-czas[pier]))*r2;
kol.emplace((long long)ceil((double)(czas[pier+nr]-czas[pier])/(nr)), pier+nr-1);
}
}
for(int i=1; i<=1000000; i++) pre[i]+=pre[i-1];
for(int i=1; i<=1000000; i++) pre[i]+=pre[i-1]+dod[i];
for(int i=0, a; i<m; i++)
{
scanf("%d", &a);
printf("%lld\n", pre[a]);
}
}
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 | #include <iostream> #include <algorithm> #include <assert.h> #include <queue> #define mp make_pair using namespace std; long long czas[300001]; int ojc[300001]; int roz[300001]; int mn[300001]; int find(int poz) { if(ojc[poz]==-1) return poz; ojc[poz]=find(ojc[poz]); return ojc[poz]; } void merge(int a, int b) { int fa=find(a); int fb=find(b); if(fa!=fb) { if(roz[fa]<roz[fb]) { fa^=fb; fb^=fa; fa^=fb; } roz[fa]+=roz[fb]; ojc[fb]=fa; mn[fa]=min(mn[fa], mn[fb]); } } long long pre[2000001]; long long dod[2000001]; int main() { long long n, m; scanf("%lld%lld", &n, &m); for(int i=0; i<=n; i++) ojc[i]=-1; for(int i=0; i<=n; i++) roz[i]=1; for(int i=0; i<=n; i++) mn[i]=i; for(int i=1; i<=n; i++) scanf("%lld", &czas[i]); czas[n+1]=1e18; priority_queue <pair <long long, int>, vector <pair <long long, int> >, greater<pair <long long, int> > > kol; for(int i=1; i<=n; i++) { kol.push(mp(czas[i]-czas[i-1], i-1)); } while(!kol.empty()) { pair <long long, int> akt=kol.top(); kol.pop(); if(akt.first>1000000) break; int f1=find(akt.second); int f2=find(akt.second+1); if(f1!=f2) { long long r1=roz[f1], r2=roz[f2]; pre[akt.first+1]-=r1*(r1-1)/2; pre[akt.first+1]-=r2*(r2-1)/2; merge(f1, f2); int nf=find(f1); long long nr=roz[nf]; int pier=mn[nf]; assert(nr==r1+r2); pre[akt.first+1]+=nr*(nr-1)/2; dod[akt.first]+=(akt.first*r1-(czas[akt.second+1]-czas[pier]))*r2; kol.emplace((long long)ceil((double)(czas[pier+nr]-czas[pier])/(nr)), pier+nr-1); } } for(int i=1; i<=1000000; i++) pre[i]+=pre[i-1]; for(int i=1; i<=1000000; i++) pre[i]+=pre[i-1]+dod[i]; for(int i=0, a; i<m; i++) { scanf("%d", &a); printf("%lld\n", pre[a]); } } |
English