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;
#define int long long
#define ii pair<int,int>
#define iii tuple<int,int,int>
#define i4 tuple<int,int,int,int>
#define fi first
#define se second
#define endl '\n'
#define puf push_front
#define pof pop_front
#define pub push_back
#define pob pop_back
#define lb lower_bound
#define ub upper_bound
#define rep(x,s,e) for (int x=(s)-((s)>(e));x!=(e)-((s)>(e));((s)<(e))?x++:x--)
#define all(x) (x).begin(),(x).end()
#define sz(x) (int) (x).size()
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
struct line{
int m,c;
int eval(int x){
return m*x+c;
}
};
struct node{
int s,e,m;
line val={0,-(int)1e18};
node *l=nullptr,*r=nullptr;
node (int _s,int _e){
s=_s,e=_e,m=s+e>>1;
}
void update(line i){
bool lo=val.eval(s)<i.eval(s);
bool mi=val.eval(m)<i.eval(m);
bool hi=val.eval(e)<i.eval(e);
if (mi) swap(i,val);
if (i.c==-1e18 || lo==hi) return;
if (lo!=mi && s!=m){
if (l==nullptr) l=new node(s,m-1);
l->update(i);
}
if (mi!=hi && m!=e){
if (r==nullptr) r=new node(m+1,e);
r->update(i);
}
}
int query(int x){
if (x<m){
if (l==nullptr) return val.eval(x);
else return max(val.eval(x),l->query(x));
}
else if (m<x){
if (r==nullptr) return val.eval(x);
else return max(val.eval(x),r->query(x));
}
else return val.eval(x);
}
} *root; //[0,2e9]
int n,q;
ii arr[2805],brr[2805];
int cost[2805];
vector<int> vx,vy;
map<int,vector<iii> > mx,my;
int up[5605][5605];
int ri[5605][5605];
int grid[5605][5605];
vector<i4> q1,q2;
int ans[3000005];
signed main(){
cin.tie(0);
cout.tie(0);
cin.sync_with_stdio(false);
cin>>n>>q;
int a,b,c;
rep(x,0,n){
cin>>a>>b>>c>>cost[x];
arr[x]={a+b,a-b};
brr[x]=arr[x];
if (b<c) brr[x].fi+=2*(c-b);
else brr[x].se+=2*(b-c);
cost[x]/=2;
}
//rep(x,0,n){
//cout<<arr[x].fi<<" "<<arr[x].se<<endl;
//cout<<brr[x].fi<<" "<<brr[x].se<<endl;
//cout<<cost[x]<<endl;
//cout<<endl;
//}
rep(x,0,n){
vx.pub(arr[x].fi),vx.pub(brr[x].fi);
vy.pub(arr[x].se),vy.pub(brr[x].se);
if (arr[x].fi==brr[x].fi) mx[arr[x].fi].pub({arr[x].se,brr[x].se,cost[x]});
else my[arr[x].se].pub({arr[x].fi,brr[x].fi,cost[x]});
}
sort(all(vx)); vx.erase(unique(all(vx)),vx.end());
sort(all(vy)); vy.erase(unique(all(vy)),vy.end());
//for (auto it:vx) cout<<it<<" "; cout<<endl;
//for (auto it:vy) cout<<it<<" "; cout<<endl;
rep(x,0,sz(vx)){
vector<iii> v=mx[vx[x]];
vector<ii> ins,del;
for (auto [a,b,c]:v){
ins.pub({a,c});
del.pub({b,c});
}
sort(all(ins)); reverse(all(ins));
sort(all(del)); reverse(all(del));
multiset<int,greater<int> > s;
rep(y,0,sz(vy)){
while (!ins.empty() && ins.back().fi==vy[y]){
s.insert(ins.back().se);
ins.pob();
}
while (!del.empty() && del.back().fi==vy[y]){
s.erase(s.find(del.back().se));
del.pob();
}
if (!s.empty()) up[x][y+1]=*s.begin();
}
}
rep(y,0,sz(vy)){
vector<iii> v=my[vy[y]];
vector<ii> ins,del;
for (auto [a,b,c]:v){
ins.pub({a,c});
del.pub({b,c});
}
sort(all(ins)); reverse(all(ins));
sort(all(del)); reverse(all(del));
multiset<int,greater<int> > s;
rep(x,0,sz(vx)){
while (!ins.empty() && ins.back().fi==vx[x]){
s.insert(ins.back().se);
ins.pob();
}
while (!del.empty() && del.back().fi==vx[x]){
s.erase(s.find(del.back().se));
del.pob();
}
if (!s.empty()) ri[x+1][y]=*s.begin();
}
}
//rep(x,0,sz(vx)){
//rep(y,0,sz(vy)) cout<<up[x][y]<<" "; cout<<endl;
//} cout<<endl;
//rep(x,0,sz(vx)){
//rep(y,0,sz(vy)) cout<<ri[x][y]<<" "; cout<<endl;
//} cout<<endl;
rep(x,sz(vx),0) rep(y,sz(vy),0){
if (x!=sz(vx)-1){
grid[x][y]=max(grid[x][y],grid[x+1][y]+ri[x+1][y]*(vx[x+1]-vx[x]));
}
if (y!=sz(vy)-1){
grid[x][y]=max(grid[x][y],grid[x][y+1]+up[x][y+1]*(vy[y+1]-vy[y]));
}
}
//rep(x,0,sz(vx)){
//rep(y,0,sz(vy)) cout<<grid[x][y]<<" "; cout<<endl;
//} cout<<endl;
rep(x,0,q){
cin>>a>>b;
tie(a,b)=ii(a+b,a-b);
//cout<<a<<" "<<b<<endl;
a=max(a,vx[0]),b=max(b,vy[0]);
if (a>vx.back() || b>vy.back()) continue;
int a2=lb(all(vx),a)-vx.begin(),b2=lb(all(vy),b)-vy.begin();
q1.pub({b2,a2,b,x});
q2.pub({a2,b2,a,x});
//int ans=0;
//rep(x,a2,sz(vx)){
//int temp=grid[x][b2]+up[x][b2]*(vy[b2]-b);
//ans=max(ans,temp);
//}
//rep(y,b2,sz(vy)){
//int temp=grid[a2][y]+ri[a2][y]*(vx[a2]-a);
//ans=max(ans,temp);
//}
//cout<<ans<<endl;
}
sort(all(q1)); sort(all(q2));
rep(y,sz(vy),0){ //process q1
root=new node(-1000000000,2000000000);
rep(x,sz(vx),0){
root->update({-up[x][y],grid[x][y]+up[x][y]*vy[y]});
while (!q1.empty() && get<0>(q1.back())==y && get<1>(q1.back())==x){
int b=get<2>(q1.back()),idx=get<3>(q1.back()); q1.pob();
ans[idx]=max(ans[idx],root->query(b));
}
}
}
rep(x,sz(vx),0){ //process q1
root=new node(-1000000000,2000000000);
rep(y,sz(vy),0){
root->update({-ri[x][y],grid[x][y]+ri[x][y]*vx[x]});
while (!q2.empty() && get<0>(q2.back())==x && get<1>(q2.back())==y){
int a=get<2>(q2.back()),idx=get<3>(q2.back()); q2.pob();
ans[idx]=max(ans[idx],root->query(a));
}
}
}
rep(x,0,q) cout<<ans[x]<<endl;
}
Compilation message (stderr)
bodyguard.cpp: In constructor 'node::node(long long int, long long int)':
bodyguard.cpp:39:16: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
39 | s=_s,e=_e,m=s+e>>1;
| ~^~
# | 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... |