#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#define MAX_N 200002
using namespace std;
struct Group
{
Group *p;
unsigned long long int size;
unsigned long long int start_time;
unsigned long long int start_index;
unsigned long long int end_index;
Group(unsigned long long int size,unsigned long long int start_time,unsigned long long int start_index,unsigned long long int end_index):size(size),start_time(start_time),start_index(start_index),end_index(end_index),p(nullptr){}
Group(){}
};
Group groups[MAX_N];
unsigned long long int client_time[MAX_N];
unsigned long long int sum[MAX_N];
unsigned int n,m;
unsigned long long int sum_d=0;
unsigned long long int diff=0;
set<pair<long long int,int>> event;
Group* parent(Group *a)
{
Group* cur = a;
if(cur->p != nullptr)
cur->p = parent(cur->p);
else return cur;
return cur->p;
}
bool merge(Group &a,Group &b) // left a
{
Group *pa=parent(&a);
Group *pb=parent(&b);
if(pa == pb)return false;
//cout << diff << " " << sum_d << " " << pb->size << " " << pa->size << " "<< pb->start_time << " " << pa->start_time << "\n";
diff += pb->size*(pb->start_time - pa->start_time);
sum_d += sum[pa->size+pb->size-1] - sum[pa->size-1] - sum[pb->size-1];
//cout << diff << " " << sum_d << "\n";
pb->p=pa;
pa->size+=pb->size;
//pa->end_index = pb->end_index;
pa->end_index = max(pa->end_index,pb->end_index);
pa->start_index = min(pa->start_index,pb->start_index);
pa->start_time = min(pa->start_time,pb->start_time);
return true;
}
void init()
{
for(int i=1;i<MAX_N;++i)
sum[i] = sum[i-1]+i;
}
vector<long long int> cookingTime;
bool cmp(const int a,const int b)
{
return cookingTime[a] < cookingTime[b];
}
int main()
{
std::ios::sync_with_stdio(false);
init();
long long int d;
cin >> n >> m;
groups[0] = Group(1,0,0,0);
for(int i=1;i<=n;++i)
{
cin >> client_time[i];
groups[i] = Group(1,client_time[i],i,i);
long long int dt = client_time[i]-client_time[i-1];
event.insert(make_pair(dt,i));//[dt] = i;
}
cookingTime.resize(m);
for(int i=0;i<m;++i)
{
cin >> d;
cookingTime[i] = d;
}
vector<int> pos(m);
vector<long long int> res(m);
for(int i=0;i<m;++i)
pos[i]=i;
sort(pos.begin(),pos.end(),cmp);
for(auto p : pos)
{
long long int it = cookingTime[p];
while(event.begin() != event.end()&& event.begin()->first<=it)
{
int idx = event.begin()->second;
if(merge(groups[idx-1],groups[idx])){
int end_index = parent(&groups[idx-1])->end_index;
if(end_index<n)
{
long long int dt = client_time[end_index+1] - parent(&groups[idx-1])->start_time;
long long int newTime = (dt)/(parent(&groups[idx-1])->size);
if((dt)%(parent(&groups[idx-1])->size))newTime++;
event.insert(std::pair<long long int,int>(newTime,end_index+1));
}
}
event.erase(event.begin());
}
res[p] = it*sum_d-diff;
}
for(auto it : res)
cout << it << "\n";
}
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 116 | #include <iostream> #include <algorithm> #include <map> #include <vector> #include <set> #define MAX_N 200002 using namespace std; struct Group { Group *p; unsigned long long int size; unsigned long long int start_time; unsigned long long int start_index; unsigned long long int end_index; Group(unsigned long long int size,unsigned long long int start_time,unsigned long long int start_index,unsigned long long int end_index):size(size),start_time(start_time),start_index(start_index),end_index(end_index),p(nullptr){} Group(){} }; Group groups[MAX_N]; unsigned long long int client_time[MAX_N]; unsigned long long int sum[MAX_N]; unsigned int n,m; unsigned long long int sum_d=0; unsigned long long int diff=0; set<pair<long long int,int>> event; Group* parent(Group *a) { Group* cur = a; if(cur->p != nullptr) cur->p = parent(cur->p); else return cur; return cur->p; } bool merge(Group &a,Group &b) // left a { Group *pa=parent(&a); Group *pb=parent(&b); if(pa == pb)return false; //cout << diff << " " << sum_d << " " << pb->size << " " << pa->size << " "<< pb->start_time << " " << pa->start_time << "\n"; diff += pb->size*(pb->start_time - pa->start_time); sum_d += sum[pa->size+pb->size-1] - sum[pa->size-1] - sum[pb->size-1]; //cout << diff << " " << sum_d << "\n"; pb->p=pa; pa->size+=pb->size; //pa->end_index = pb->end_index; pa->end_index = max(pa->end_index,pb->end_index); pa->start_index = min(pa->start_index,pb->start_index); pa->start_time = min(pa->start_time,pb->start_time); return true; } void init() { for(int i=1;i<MAX_N;++i) sum[i] = sum[i-1]+i; } vector<long long int> cookingTime; bool cmp(const int a,const int b) { return cookingTime[a] < cookingTime[b]; } int main() { std::ios::sync_with_stdio(false); init(); long long int d; cin >> n >> m; groups[0] = Group(1,0,0,0); for(int i=1;i<=n;++i) { cin >> client_time[i]; groups[i] = Group(1,client_time[i],i,i); long long int dt = client_time[i]-client_time[i-1]; event.insert(make_pair(dt,i));//[dt] = i; } cookingTime.resize(m); for(int i=0;i<m;++i) { cin >> d; cookingTime[i] = d; } vector<int> pos(m); vector<long long int> res(m); for(int i=0;i<m;++i) pos[i]=i; sort(pos.begin(),pos.end(),cmp); for(auto p : pos) { long long int it = cookingTime[p]; while(event.begin() != event.end()&& event.begin()->first<=it) { int idx = event.begin()->second; if(merge(groups[idx-1],groups[idx])){ int end_index = parent(&groups[idx-1])->end_index; if(end_index<n) { long long int dt = client_time[end_index+1] - parent(&groups[idx-1])->start_time; long long int newTime = (dt)/(parent(&groups[idx-1])->size); if((dt)%(parent(&groups[idx-1])->size))newTime++; event.insert(std::pair<long long int,int>(newTime,end_index+1)); } } event.erase(event.begin()); } res[p] = it*sum_d-diff; } for(auto it : res) cout << it << "\n"; } |
English