[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;
}

posted @ 2018-07-29 13:15  cjfdf  阅读(128)  评论(0编辑  收藏  举报