P3309 [SDOI2014] 向量集
\[ans=\max\{zx+wy\}\to
\\\frac{ans}{w}=\max\{\frac{z}{w}x+y\}
\]
斜率优化的形式,答案一定在上凸包上。而这道题要维护区间凸包。
考虑线段树,预处理区间凸包复杂度是 \(O(len)\) 的,这样复杂度是 \(O(n^2)\) 的。
但是每个区间只有在所有凸包全部插入后才有可能被询问到,所以每个区间实际上只用预处理一次,类似二进制分组。所以复杂度 \(O(n\log n)\),而询问在每个区间的凸包上二分即可,\(O(n\log^2n)\)。
luogu 最优解到底多快啊,怎么 1.5s 还卡不过去 /fn。
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cfast ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define ll long long
#define intz(x,y) memset((x),(y),sizeof((x)))
//void write(int x){cout<<x<<' ';}
//void write(pii x){cout<<"P("<<x.fi<<','<<x.se<<")\n";}
//void write(vector<auto>x){for(auto i:x)write(i);cout<<'\n';}
//void write(auto *a,int l,int r){for(int i=l;i<=r;i++)write(a[i]);cout<<'\n';}
#define pcount(x) __builtin_popcount(x)
inline void cmx(auto &x,ll y){if(y>x)x=y;}
const int N=4e5+5;
pii a[N];ll lst;
struct node{int l,r,mx,my;bool fl;basic_string<pii>w;}t[N<<2];
void build(int u,int l,int r){
t[u]={l,r};if(l==r)return;int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
inline bool chk(pii &x,pii &y,pii &z){return 1ll*(x.se-y.se)*(z.fi-y.fi)>1ll*(z.se-y.se)*(x.fi-y.fi);}
inline void get(int &u){
basic_string<pii>p;
t[u].fl=1;int l=t[u].l,r=t[u].r;
for(int i=l;i<=r;i++)p.pb(a[i]);
sort(p.begin(),p.end());
for(pii z:p){
while(t[u].w.size()>1){
pii x=t[u].w.back(),y=t[u].w[t[u].w.size()-2];
if(!chk(x,y,z))t[u].w.pop_back();else break;
}t[u].w.pb(z);
}
}
void upd(int u,int &d){
cmx(t[u].mx,a[d].fi),cmx(t[u].my,a[d].se);
if(t[u].l==t[u].r)return;
int mid=t[u].l+t[u].r>>1;
(d<=mid?upd(u<<1,d):upd(u<<1|1,d));
}
inline ll calc(int u,int &x,int &y){
if(!y)return 1ll*t[u].mx*x;
if(!x)return 1ll*t[u].my*y;
int l=0,r=t[u].w.size()-2,mid;
while(l<=r)(mid=l+r>>1,1ll*(t[u].w[mid+1].se-t[u].w[mid].se)*y>=1ll*(-x)*(t[u].w[mid+1].fi-t[u].w[mid].fi)?l=mid+1:r=mid-1);
return (1ll*x*t[u].w[l].fi+1ll*t[u].w[l].se*y);
}
ll query(int u,int l,int r,int &x,int &y){
if(t[u].l>=l&&t[u].r<=r){
if(!t[u].fl)get(u);
return calc(u,x,y);
}
int mid=t[u].l+t[u].r>>1;ll mx=-1e18;
if(l<=mid)mx=query(u<<1,l,r,x,y);
if(r>mid)cmx(mx,query(u<<1|1,l,r,x,y));
return mx;
}
inline int decode(int x){return x^(lst&0x7fffffff);}
inline void UesugiErii(){
int n,tot=0;char C;cin>>n>>C;
build(1,1,n);
char op;int x,y,l,r;
while(n--){
cin>>op>>x>>y;
if(op=='A'){
if(C!='E')x=decode(x),y=decode(y);
a[++tot]=mp(x,y);upd(1,tot);
}else{
cin>>l>>r;
if(C!='E')x=decode(x),y=decode(y),l=decode(l),r=decode(r);
cout<<(lst=query(1,l,r,x,y))<<'\n';
}
}
}
signed main(){
//IO();
cfast;
int _=1;//cin>>_;
for(;_;_--)UesugiErii();
return 0;
}

浙公网安备 33010602011771号