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<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
struct A{
ll sx, fx, h;
A(){}
A(ll a, ll b, ll c) : sx(a), fx(b), h(c) {}
};
struct uf{
vector<int> par;
vector<ll> h, sx, fx;
uf(int a, A arr[]){
par.resize(a+5,-1);
h.resize(a+5);
sx.resize(a+5);
fx.resize(a+5);
for(int i=1 ; i<=a ; i++) h[i]=arr[i].h, sx[i]=arr[i].sx, fx[i]=arr[i].fx;
}
int f(int x){
if(par[x]==-1) return x;
par[x]=f(par[x]);
return par[x];
}
void u(int x, int y){
x=f(x), y=f(y);
ll s=min(sx[x],sx[y]), f=max(fx[x],fx[y]);
if(h[x]<h[y]) par[y]=x, sx[x]=s, fx[x]=f;
else par[x]=y, sx[y]=s, fx[y]=f;
}
ll get_h(int x){return h[f(x)];}
ll get_sx(int x){return sx[f(x)];}
ll get_fx(int x){return fx[f(x)];}
};
struct Node{
vector<P> val;
Node(){}
Node& operator=(const Node &rhs){
val.resize(0);
for(P x : rhs.val) val.push_back(x);
return *this;
}
Node operator+(const Node &rhs) const{
Node ret;
int i=0, j=0, sz0=val.size(), sz1=rhs.val.size(), cur=0;
ret.val.resize(sz0+sz1);
for(i=0, j=0 ; i<sz0 && j<sz1 ;){
if(val[i].first<=rhs.val[j].first) ret.val[cur++]=val[i++];
else ret.val[cur++]=rhs.val[j++];
}
for(i ; i<sz0 ; i++) ret.val[cur++]=val[i];
for(j ; j<sz1 ; j++) ret.val[cur++]=rhs.val[j];
return ret;
}
};
struct Q{
ll sx, fx, v;
Q(){}
Q(ll a, ll b, ll c) : sx(a), fx(b), v(c) {}
};
struct SegTree{
vector<ll> tree, lazy;
vector<int> idx;
int base;
SegTree(int a){
base=1;
while(base<a) base<<=1;
tree.resize(base*2);
lazy.resize(base*2);
idx.resize(base*2);
base--;
for(int i=1 ; i<=a ; i++) idx[base+i]=i;
for(int i=base ; i>=1 ; i--) idx[i]=max(idx[i*2],idx[i*2+1]);
}
void propagate(int num){
if(lazy[num]!=0){
if(num<=base){
lazy[num*2]+=lazy[num];
lazy[num*2+1]+=lazy[num];
}
tree[num]+=lazy[num]; lazy[num]=0;
}
}
void update(ll val, int st, int fn, int ns=1, int nf=-1, int num=1){
if(nf==-1) nf=base+1;
propagate(num);
if(fn<ns || nf<st) return;
if(st<=ns && nf<=fn){
lazy[num]+=val; propagate(num);
return;
}
int mid=(ns+nf)>>1;
update(val,st,fn,ns,mid,num*2);
update(val,st,fn,mid+1,nf,num*2+1);
tree[num]=max(tree[num*2],tree[num*2+1]);
if(tree[num]==tree[num*2]) idx[num]=idx[num*2];
else idx[num]=idx[num*2+1];
}
ll get_val(){ return tree[1]; }
int get_idx(){ return idx[1]; }
};
bool cmp1(const A &lhs, const A &rhs){
return lhs.h>rhs.h;
}
bool cmp2(const Q &lhs, const Q &rhs){
return lhs.sx<rhs.sx;
}
int n, k, n2, bs, sz, num[300005];
ll m[300005][2], xv[150005];
A flr[150005];
bool fcheck[150005], used[300005];
vector<Q> qry;
vector<Node> mtree;
void del_qry(int num, int idx, SegTree &T)
{
int sz=mtree[num].val.size();
for(int i=sz-1 ; i>=0 ; i--){
int c=mtree[num].val[i].first;
int j=mtree[num].val[i].second;
if(c>=idx){
if(!used[j]) T.update(-qry[j].v,qry[j].sx,qry[j].fx), used[j]=true;
sz--;
}
else break;
}
mtree[num].val.resize(sz);
}
void solve(int idx, SegTree &T){
int st=bs+1, fn=bs+num[idx];
while(st<fn){
if(st&1){
del_qry(st,idx,T);
st++;
}
if(!(fn&1)){
del_qry(fn,idx,T);
fn--;
}
st>>=1, fn>>=1;
}
if(st==fn) del_qry(st,idx,T);
}
int main()
{
scanf("%d",&n);
for(int i=1 ; i<=n ; i++){
scanf("%lld %lld",&m[i][0],&m[i][1]);
if(i>1 && i&1){
n2++;
flr[n2]=A(n2,n2,m[i][1]);
xv[n2+1]=m[i][0];
}
}
scanf("%d",&k);
uf uT(n2,flr);
sort(flr+1,flr+1+n2,cmp1);
for(int i=1 ; i<=n2 ; i++){
A val=flr[i];
if(val.sx>1 && fcheck[val.sx-1]){
A ret(uT.get_sx(val.sx-1),uT.get_fx(val.sx-1),uT.get_h(val.sx-1));
if(val.h!=ret.h) qry.emplace_back(ret.sx,ret.fx,(xv[ret.fx+1]-xv[ret.sx])*(ret.h-val.h));
uT.u(val.sx-1,val.sx);
}
if(val.fx+1<=n2 && fcheck[val.fx+1]){
A ret(uT.get_sx(val.fx+1),uT.get_fx(val.fx+1),uT.get_h(val.fx+1));
if(val.h!=ret.h) qry.emplace_back(ret.sx,ret.fx,(xv[ret.fx+1]-xv[ret.sx])*(ret.h-val.h));
uT.u(val.fx+1,val.sx);
}
fcheck[val.sx]=true;
}
if(flr[n2].h!=0) qry.emplace_back(1,n2,xv[n2+1]*flr[n2].h);
sort(qry.begin(),qry.end(),cmp2);
sz=qry.size();
for(int i=1, j=0 ; i<=n2 ; i++){
while(j<sz && qry[j].sx<=i) j++;
num[i]=j;
}
bs=1;
while(bs<sz) bs<<=1;
mtree.resize(bs*2); bs--;
for(int i=0 ; i<sz ; i++) mtree[bs+i+1].val.push_back(P(qry[i].fx,i));
for(int i=bs ; i>=1 ; i--) mtree[i]=mtree[i*2]+mtree[i*2+1];
SegTree T(n2);
for(Q x : qry) T.update(x.v,x.sx,x.fx);
ll ans=0;
for(int i=1 ; i<=k ; i++){
ll maxv=T.get_val();
int idx=T.get_idx();
if(maxv==0) break;
ans+=maxv;
solve(idx,T);
}
printf("%lld",ans);
return 0;
}
Compilation message (stderr)
aqua3.cpp: In member function 'Node Node::operator+(const Node&) const':
aqua3.cpp:55:13: warning: statement has no effect [-Wunused-value]
55 | for(i ; i<sz0 ; i++) ret.val[cur++]=val[i];
| ^
aqua3.cpp:56:13: warning: statement has no effect [-Wunused-value]
56 | for(j ; j<sz1 ; j++) ret.val[cur++]=rhs.val[j];
| ^
aqua3.cpp: In function 'int main()':
aqua3.cpp:157:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
157 | scanf("%d",&n);
| ~~~~~^~~~~~~~~
aqua3.cpp:159:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
159 | scanf("%lld %lld",&m[i][0],&m[i][1]);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
aqua3.cpp:166:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
166 | scanf("%d",&k);
| ~~~~~^~~~~~~~~
# | 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... |