This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "nile.h"
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <deque>
#include <list>
#include <iomanip>
#include <stdlib.h>
#include <time.h>
#include <cstring>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
#define REP(i,a,b) for(ll i=(ll) a; i<(ll) b; i++)
#define pb push_back
#define mp make_pair
#define pl pair<ll,ll>
#define ff first
#define ss second
#define whole(x) x.begin(),x.end()
#define DEBUG(i) cout<<"Pedro "<<i<<endl
#define INF 1000000000000000000LL
#define EPS ((ld)0.00000000001)
#define pi ((ld)3.141592653589793)
#define VV(vvvv,NNNN,xxxx); REP(iiiii,0,NNNN) {vvvv.pb(xxxx);}
ll mod=1000000007;
template<class A=ll>
void Out(vector<A> a) {REP(i,0,a.size()) {cout<<a[i]<<" ";} cout<<endl;}
template<class A=ll>
void In(vector<A> &a, ll N) {A cur; REP(i,0,N) {cin>>cur; a.pb(cur);}}
class ST
{
public:
ll N;
class SV //seg value
{
public:
ll a;
SV() {a=INF;}
SV(ll x) {a=x;}
SV operator & (SV X) {SV ANS(min(a,X.a)); return ANS;}
};
class LV //lazy value
{
public:
ll a;
LV() {a=0LL;}
LV(ll x) {a=x;}
LV operator & (LV X) {LV ANS(a+X.a); return ANS;}
};
SV upval(ll c) //how lazy values modify a seg value inside a node, c=current node
{
SV X(p[c].a+lazy[c].a);
return X;
}
SV neuts; LV neutl;
vector<SV> p;
vector<LV> lazy;
vector<pl> range;
ST() {N=0LL;}
ST(vector<ll> arr)
{
N = (ll) 1<<(ll) ceil(log2(arr.size()));
REP(i,0,2*N) {range.pb(mp(0LL,0LL));}
REP(i,0,N) {p.pb(neuts);}
REP(i,0,arr.size()) {SV X(arr[i]); p.pb(X); range[i+N]=mp(i,i);}
REP(i,arr.size(),N) {p.pb(neuts); range[i+N]=mp(i,i);}
ll cur = N-1;
while(cur>0)
{
p[cur]=p[2*cur]&p[2*cur+1];
range[cur]=mp(range[2*cur].ff,range[2*cur+1].ss);
cur--;
}
REP(i,0,2*N) {lazy.pb(neutl);}
}
void prop(ll c) //how lazy values propagate
{
p[c] = upval(c);
lazy[2*c]=lazy[c]&lazy[2*c]; lazy[2*c+1]=lazy[c]&lazy[2*c+1];
lazy[c]=neutl;
}
SV query(ll a,ll b, ll c=1LL) //range [a,b], current node. initially: query(a,b)
{
if(a>b) {return neuts;}
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return neuts;}
if(x>=a && y<=b) {return upval(c);}
prop(c);
SV ans = query(a,b,2*c)&query(a,b,2*c+1);
return ans;
}
void update(LV s, ll a, ll b, ll c=1LL) //update LV, range [a,b], current node, current range. initially: update(s,a,b)
{
if(a>b) {return;}
ll x=range[c].ff; ll y=range[c].ss;
if(y<a || x>b) {return ;}
if(x>=a && y<=b)
{
lazy[c]=s&lazy[c];
return;
}
prop(c);
update(s,a,b,2*c); update(s,a,b,2*c+1);
p[c]=upval(2*c)&upval(2*c+1);
}
};
ST S_odd, S_even, S_over_odd, S_over_even;
class DSU //with range compression and union by subtree size
{
public:
ll N;
vector<ll> p,siz; vector<pl> range;
vector<ll> cost;
DSU(ll n)
{
N=n; REP(i,0,N) {p.pb(i); siz.pb(1); range.pb({i,i});}
}
ll find(ll x)
{
if(p[x]==x) {return x;}
ll ans=find(p[x]);
p[x]=ans;
return ans;
}
void update_cost(ll x)
{
if(siz[x]%2==0) {cost[x]=0;}
else
{
if(range[x].ff%2==0) {cost[x]=min(S_even.query(range[x].ff,range[x].ss).a,S_over_odd.query(range[x].ff,range[x].ss).a);}
else {cost[x]=min(S_odd.query(range[x].ff,range[x].ss).a,S_over_even.query(range[x].ff,range[x].ss).a);}
}
}
void unionn(ll a, ll b)
{
a=find(a); b=find(b);
if(a==b) {return;}
if(siz[a]>siz[b]) {swap(a,b);}
p[a]=b; siz[b]+=siz[a];
range[b] = {min(range[a].ff,range[b].ff),max(range[a].ss,range[b].ss)};
update_cost(b);
}
vector<vector<ll> > EquivalenceClasses() //O(N)
{
vector<vector<ll> > rep; REP(i,0,N) {rep.pb({});}
REP(i,0,N) {rep[find(i)].pb(i);}
vector<vector<ll> > CC;
REP(i,0,N) {if(rep[i].size()>0) {CC.pb(rep[i]);}}
return CC;
}
};
vector<ll> calculate_costs(vector<int> weights, vector<int> AA, vector<int> BB, vector<int> E)
{
ll N = weights.size(); ll Q = E.size();
vector<pl> weights_order; REP(i,0,N) {weights_order.pb({weights[i],i});}
sort(whole(weights_order));
vector<ll> w(N,0);
vector<ll> cost(N,0); ll ind;
ll basis_cost = 0; REP(i,0,N) {ind = weights_order[i].ss; w[i]=weights[ind]; basis_cost+=BB[ind]; cost[i]=AA[ind]-BB[ind];}
vector<pl> queries; REP(q,0,Q) {queries.pb({E[q],q});}
sort(whole(queries));
DSU X(N); X.cost = cost;
vector<pl> dist,dist_double;
REP(i,0,N-1) {dist.pb({w[i+1]-w[i],i});}
REP(i,1,N-1) {dist_double.pb({w[i+1]-w[i-1],i});}
sort(whole(dist)); sort(whole(dist_double));
vector<ll> ans(Q,0); ll query_ind; ll D;
ll dist_ind=0; ll dist_double_ind=0;
ll curans=0; REP(i,0,N) {curans+=cost[i];}
ll A,B;
vector<ll> xx(N,INF); S_even = ST(xx); S_odd = ST(xx); S_over_even = ST(xx); S_over_odd = ST(xx);
REP(i,0,N)
{
if(i%2==0) {S_even.update(cost[i]-INF,i,i);}
else {S_odd.update(cost[i]-INF,i,i);}
}
REP(q,0,Q)
{
query_ind = queries[q].ss; D = queries[q].ff;
while(dist_ind < dist.size() && dist[dist_ind].ff<=D)
{
ind = dist[dist_ind].ss;
A = X.find(ind); B = X.find(ind+1);
curans-=X.cost[A]; curans-=X.cost[B];
X.unionn(A,B); A = X.find(A); curans+=X.cost[A];
dist_ind++;
}
while(dist_double_ind < dist_double.size() && dist_double[dist_double_ind].ff<=D)
{
ind = dist_double[dist_double_ind].ss;
if(ind%2==0) {S_over_even.update(cost[ind]-INF,ind,ind);}
else {S_over_odd.update(cost[ind]-INF,ind,ind);}
A = X.find(ind); curans-=X.cost[A];
X.update_cost(A); curans+=X.cost[A];
dist_double_ind++;
}
ans[query_ind]=curans+basis_cost;
}
return ans;
}
Compilation message (stderr)
nile.cpp:2: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
2 | #pragma GCC optimization ("O3")
|
nile.cpp:3: warning: ignoring '#pragma GCC optimization' [-Wunknown-pragmas]
3 | #pragma GCC optimization ("unroll-loops")
|
nile.cpp: In function 'std::vector<long long int> calculate_costs(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
nile.cpp:214:24: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
214 | while(dist_ind < dist.size() && dist[dist_ind].ff<=D)
| ~~~~~~~~~^~~~~~~~~~~~~
nile.cpp:222:31: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, long long int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
222 | while(dist_double_ind < dist_double.size() && dist_double[dist_double_ind].ff<=D)
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |