Codeforces 1221F. Choose a Square

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    传送门

    对于某个点 $(x,y)$ ,不妨设 $x<y$ 因为如果 $x>y$ 直接按 $y=x$ 对称一下即可

    当且仅当正方形左下角 $(a,a)$ 满足 $a<=x$,右上角 $(b,b)$ 满足 $b>=y$ ,才能得到这个点的价值

    所以发现其实是个二维偏序的问题,直接把 $(a,b)$ 看成另一个平面上的点,$(x,y)$ 放到那个平面上

    这样就问题变成选一个点 $(a,b)$ ,你得到的价值为所有 $x>=a$ 并且 $y<=b$ 的点 $(x,y)$ 的价值和再减去 $a,b$ 之间的差值

    考虑把点按第一关键字 $x$ 从大到小,按第二关键字 $y$ 从小到大排序,维护一个线段树表示当前 $a=x$ 的情况下 $y$ 取各个值时能够得到的最大价值

    因为当前 $a=x$ 的情况下,所有 $x>a$ 的点的代价都加入了,每次加入一个点以后直接查询线段树上 $b>=y$ 和下一个点 $b<=y'-1$ 之间的那一段的最大价值,当然如果下一个点的 $x$ 和当前点不同,那么查询直接查询当前点到线段树最大位置的值即可

    发现这样是有问题的,因为对于不同的 $b=y$ ,直接取点的值最大还不行,因为代价还要考虑 $-(y-x)$,所以线段树上维护的应该是点值和再减 $y$ 以后的最大值,当然要随便维护一下取最大值时 $b$ 的值

    然后就没了,代码因为主体是比赛时写的,可能比较丑,但是还能看...吧

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
    int x=,f=; char ch=getchar();
    while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
    while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
    return x*f;
    }
    const int N=1e6+;
    const ll INF=1e18;
    int n,x[N],y[N],c[N],t[N],xx[N],yy[N];
    struct dat {
    int l,r,val,id;
    dat (int _l=,int _r=,int _val=,int _id=) { l=_l,r=_r,val=_val,id=_id; }
    inline bool operator < (const dat &tmp) const {
    if(l!=tmp.l) return l>tmp.l;
    return r!=tmp.r ? r<tmp.r : val>tmp.val;
    }
    }d[N];
    int tot;
    int inv[N];
    struct SegTree {
    ll T[N<<],id[N<<],tag[N<<];
    inline void pushup(int o) { T[o]=max(T[o<<],T[o<<|]); id[o]=T[o<<]>=T[o<<|] ? id[o<<] : id[o<<|]; }
    inline void pushdown(int o,int l,int r)
    {
    if(!o||!tag[o]) return;
    T[o]+=tag[o]; if(l==r) { tag[o]=; return; }
    tag[o<<]+=tag[o]; tag[o<<|]+=tag[o];
    tag[o]=;
    }
    void build(int o,int l,int r)
    {
    if(l==r) { id[o]=l; T[o]=-inv[l]; return; }
    int mid=l+r>>; build(o<<,l,mid); build(o<<|,mid+,r);
    pushup(o);
    }
    inline void change(int o,int l,int r,int ql,int qr,int v)
    {
    pushdown(o,l,r);
    if(l>qr||r<ql) return;
    if(l>=ql&&r<=qr) { tag[o]=v; pushdown(o,l,r); return; }
    int mid=l+r>>;
    change(o<<,l,mid,ql,qr,v); change(o<<|,mid+,r,ql,qr,v);
    pushup(o);
    }
    ll pos,val;
    inline void query(int o,int l,int r,int ql,int qr)
    {
    pushdown(o,l,r);
    if(l>qr||r<ql) return;
    if(l>=ql&&r<=qr) { if(T[o]>val) val=T[o],pos=id[o]; return; }
    int mid=l+r>>; query(o<<,l,mid,ql,qr); query(o<<|,mid+,r,ql,qr);
    pushup(o);
    }
    }ST;
    int main()
    {
    n=read();
    for(int i=;i<=n;i++) xx[i]=x[i]=read(),yy[i]=y[i]=read(),c[i]=read();
    for(int i=;i<=n;i++) t[++tot]=x[i],t[++tot]=y[i];
    sort(t+,t+tot+); tot=unique(t+,t+tot+)-t-;
    for(int i=;i<=n;i++) x[i]=lower_bound(t+,t+tot+,x[i])-t;
    for(int i=;i<=n;i++) y[i]=lower_bound(t+,t+tot+,y[i])-t;
    int ansx=,ansy=;
    for(int i=;i<=n;i++)
    {
    if(x[i]>y[i]) swap(x[i],y[i]),swap(xx[i],yy[i]);
    d[i]=dat(x[i],y[i],c[i],i);
    ansx=max(ansx,yy[i]+); ansy=max(ansy,yy[i]+);
    inv[x[i]]=xx[i]; inv[y[i]]=yy[i];
    }
    sort(d+,d+n+); ll ans=; ST.build(,,tot);
    d[n+].l=-;
    for(int i=;i<=n;i++)
    {
    ST.change(,,tot,d[i].r,tot,d[i].val);
    ST.val=-INF; ST.pos=;
    if(d[i].l==d[i+].l) ST.query(,,tot,d[i].r,d[i+].r-);
    else ST.query(,,tot,d[i].r,tot);
    ll res=ST.val+inv[d[i].l];
    if(res>ans) ans=res,ansx=inv[d[i].l],ansy=inv[ST.pos];
    }
    printf("%lld\n",ans);
    printf("%d %d %d %d\n",ansx,ansx,ansy,ansy);
    return ;
    }
  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    “Codeforces 1221F. Choose a Square” 的相关文章

    Java8 CompletableFuture异步多线程怎么实现 - 开发技术

    这篇文章主要介绍了Java8 CompletableFuture异步多线程怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java8 CompletableFuture异步多线程怎么实现文章都会有所收获,下面我们...

    实体首部:Content-Location

    首部字段Content-Location给出与报文主体部分相对应的URI.和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI. 比如,对于使用首部字段Accept-Language的服务器驱动型请求,当返回的...

    Spring项目集成RabbitMQ及自动创建队列

    简单记录Spring项目集成RabbitMQ的过程重点记录生产者项目自动创建队列的操作因该问题给项目带来很多麻烦。 本文内容分别在Spring(V5.2.6)和Spring Boot(V2.5.14)两个项目中经过了验证下述示例代码来自于SpringBoot项目迁移到Spring项目中需稍微调整。...

    通过url删除ES中的数据

    curl -XDELETE "http://test-hostname:9200/product*_201704*"...

    PHP数组中怎么实现多条件筛选 - 编程语言

    这篇文章主要介绍“PHP数组中怎么实现多条件筛选”,在日常操作中,相信很多人在PHP数组中怎么实现多条件筛选问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP数组中怎么实现多条件筛选”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!...

    php如何删除一条数组记录 - 编程语言

    这篇文章主要介绍了php如何删除一条数组记录的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php如何删除一条数组记录文章都会有所收获,下面我们一起来看看吧。 PHP提供了许多内置函数来操作数组。你可以使用这些函...