[BZOJ4311]向量
description
solution
线段树分治+斜率优化简单题。
code
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=2e5+10;
const int T=5e6+10;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
il ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
il void file(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
}
int n,mt,qt;ll ans[N];
struct modify{int l,r,x,y;}M[N];
struct query{int id,s,x,y;}Q[N];
bool cmpm(modify a,modify b){return a.x<b.x;}
bool cmpq(query a,query b){return -1.0*a.x/a.y>-1.0*b.x/b.y;}
vector<modify>f[N<<2];vector<query>g[N<<2];
#define mid ((l+r)>>1)
#define ls (i<<1)
#define rs (i<<1|1)
void insertmodify(int i,int l,int r,int x,int y,modify m){
if(x<=l&&r<=y){f[i].pb(m);return;}
if(x<=mid)insertmodify(ls,l,mid,x,y,m);
if(mid<y)insertmodify(rs,mid+1,r,x,y,m);
}
void insertquery(int i,int l,int r,int pos,query q){
g[i].pb(q);if(l==r)return;
if(pos<=mid)insertquery(ls,l,mid,pos,q);
else insertquery(rs,mid+1,r,pos,q);
}
int l,r,que[N],quex[N],quey[N];
il dd getk(int ax,int ay,int bx,int by){
if(ax==bx)return ay>by?-inf:inf;
return 1.0*(ay-by)/(ax-bx);
}
il void work(vector<modify>F,vector<query>G){
if(!F.size()||!G.size())return;
l=1;r=0;
for(RG int i=0,sz=F.size();i<sz;i++){
RG int x=F[i].x,y=F[i].y;
while(l<r&&getk(quex[r-1],quey[r-1],quex[r],quey[r])<getk(quex[r],quey[r],x,y))r--;
r++;que[r]=i;quex[r]=x;quey[r]=y;
}
if(l<=r)
for(RG int i=0,sz=G.size();i<sz;i++){
RG dd k=-1.0*G[i].x/G[i].y;
while(l<r&&k<getk(quex[l],quey[l],quex[l+1],quey[l+1]))l++;
ans[G[i].id]=max(ans[G[i].id],1ll*F[que[l]].x*G[i].x+1ll*F[que[l]].y*G[i].y);
}
}
void segdiv(int i,int l,int r){
work(f[i],g[i]);if(l==r)return;
segdiv(ls,l,mid);segdiv(rs,mid+1,r);
}
int main()
{
n=read();
for(RG int i=1,o,id;i<=n;i++){
o=read();
if(o==1){
mt++;M[mt].l=i;
M[mt].x=read();M[mt].y=read();
}
if(o==2){id=read();M[id].r=i;}
if(o==3){
qt++;Q[qt].id=qt;Q[qt].s=i;
Q[qt].x=read();Q[qt].y=read();
}
}
sort(M+1,M+mt+1,cmpm);sort(Q+1,Q+qt+1,cmpq);
for(RG int i=1;i<=mt;i++){
if(!M[i].r)M[i].r=n;
insertmodify(1,1,n,M[i].l,M[i].r,M[i]);
}
for(RG int i=1;i<=qt;i++)
insertquery(1,1,n,Q[i].s,Q[i]);
segdiv(1,1,n);
for(RG int i=1;i<=qt;i++)printf("%lld\n",ans[i]);
return 0;
}