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

转载于:https://www.cnblogs.com/cjfdf/p/9385024.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值