codeforces 678F

codeforces 678F


有三种操作
1.将点(x,y)加入集合
2.删掉第i次操作加入的点
3.给一个数q,求x*q+y的最大值,如果当前集合为空输出”EMPTY SET”

并不会动态维护凸包,据说是用平衡树啥的。。。
换个角度想,对于每一个点都有一个存在区间[l,r],所以我们可以搞一个线段树出来,将每个点标记到线段中,然后对于每一个线段都维护一个上凸壳,然后三分求答案。
因为对于每一个点,如果将所有的标记都打上肯定是不行的,这样的话就是O(n^2),所以类似于lazy标记的样子,每个点只插入到logn个线段内,而且每个线段上的凸壳点数会少一些,均摊下来大概是O(n(logn)^2)

注意的几个点就是求上凸壳的做法,以及ans的最小值,开到-1e19大概就够了

附上代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

#define MAXN 300000
#define INF (long long)99999999999999999999

struct point
{
    long long x,y;
    point(){}
    point(long long _x,long long _y)
    {
        x=_x;y=_y;
    }
    friend point operator +(point a,point b)
    {
        return point(a.x+b.x,a.y+b.y);
    }
    friend point operator -(point a,point b)
    {
        return point(a.x-b.x,a.y-b.y);
    }
    friend long long operator ^(point a,point b)
    {
        return a.x*b.y-a.y*b.x;
    }
    friend long long operator *(point a,point b)
    {
        return a.x*b.x+a.y*b.y;
    }
    friend bool operator <(point a,point b)
    {
        return a.x==b.x?a.y<b.y:a.x<b.x;
    }
};

struct segment_tree
{
    int l,r;
    vector<point> s;
};

point s[MAXN+50];
point stack[MAXN+50];
int top;
int l[MAXN+50],r[MAXN+50];
int op[MAXN+50];
segment_tree t[5*MAXN+50];
long long ans[MAXN+50];
int flag_empty[MAXN+50];
int n;

void build(int p,int l,int r)
{
    t[p].l=l;
    t[p].r=r;
    t[p].s.clear();
    if (l==r)
    {
        return;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
}

void add(int p,int l,int r,int x)
{
    if (t[p].l==l && t[p].r==r)
    {
        t[p].s.push_back(s[x]);
        return;
    }
    int mid=(t[p].l+t[p].r)>>1;
    if (r<=mid)
    {
        add(p<<1,l,r,x);
        return;
    }
    if (l>mid)
    {
        add(p<<1|1,l,r,x);
        return;
    }
    add(p<<1,l,mid,x);
    add(p<<1|1,mid+1,r,x);
}

void ask(int x)
{
    int L=1,R=top;
    int mid1,mid2;
    while (L+3<=R)
    {
        mid1=(L*2+R)/3;
        mid2=(L+R*2)/3;
        if ((s[x]*stack[mid1])<(s[x]*stack[mid2]))
        {
            L=mid1;
        }
        else
        {
            R=mid2;
        }
    }
    for (int i=L;i<=R;i++)
    {
        ans[x]=max(ans[x],stack[i]*s[x]);
    }
}

void get(int p)
{
    if (t[p].l!=t[p].r)
    {
        get(p<<1);
        get(p<<1|1);
    }
    sort(t[p].s.begin(),t[p].s.end());
    top=0;
    int nown=t[p].s.size();
    for (int i=0;i<nown;i++)
    {
        while (top>1 && ((stack[top]-stack[top-1])^(t[p].s[i]-stack[top]))>=0) top--;
        top++;
        stack[top]=t[p].s[i];
    }
    for (int i=t[p].l;i<=t[p].r;i++)
    {
        if (op[i]==3 && flag_empty[i]) ask(i);
    }
}

int main()
{
    scanf("%d",&n);
    memset(l,0,sizeof(l));
    memset(r,0,sizeof(r));
    int now=0;
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&op[i]);
        if (op[i]==1)
        {
            scanf("%I64d%I64d",&s[i].x,&s[i].y);
            l[i]=i;
            r[i]=n;
            now++;
        }
        else
        {
            scanf("%I64d",&s[i].x);
            s[i].y=1;
        }
        if (op[i]==2)
        {
            r[s[i].x]=i;
            now--;
        }
        flag_empty[i]=now;
        ans[i]=-INF;
    }
    build(1,1,n);
    for (int i=1;i<=n;i++)
    {
        if (op[i]==1)
        {
            add(1,l[i],r[i],i);
        }
    }
    get(1);

    for (int i=1;i<=n;i++)
    {
        if (op[i]!=3) continue;
        if (flag_empty[i])
        {
            printf("%I64d\n",ans[i]);
        }
        else
        {
            printf("EMPTY SET\n");
        }
    }

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
678f网址导航精美版(免费版) 源码简介: 1:整站全部生成html,易于搜索引擎收录 2:全后台化管理,操作简单 3:新站登陆功能 4:密码md5加密 5:后台登陆验证码识别 6:后台美化 7:新站登陆验证码识别 8:网站信息设置:网站名称,网站地址,站长邮箱等 9:无需修改任何网页,安装更为简单 10:网站信息后台设置 11:优化后台管理 12:网站推荐 13:模板后台管理 14:网站维护时可设置关闭“新站登陆”功能 15:可修改后台管理目录 16:分类目录、分类页文件名后台修改 17:网站安装目录调用标签 18:网址分类集合调用标签 19:服务器信息或组件查询 20:将网址分类从页面式修改为目录式,更适宜搜索引擎收录 21:所有删除增加2次确认,防止误操作 22:采用新的网站审核机制 23:类别合并功能 24:重复域名禁止登陆功能 25:“实用酷站”管理 演示:http://www.678f.com 下载:http://678f.5944vip.com/dzy/m.rar 安装方法: 1:将源码全部上传到网站空间,进入后台管理页面 2: 点击“网站信息管理”,修改网站信息 3:点击“生成html管理”,生成网站页面 4:后台管理登陆页:http://你的网址/admin/ 5:后台管理 帐号:admin 密码:www.678f.com 注:如果你是用本地IIS访问的话有可能将无法生成html建议上传到空间 部分文件和目录介绍: admin/ 后台管理目录,建议修改 本版主要改进了后台实用性 还有不明白的可以联系本版主 本版主 QQ 362657683 火星工作室
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值