• BZOJ 2716: [Violet 3]天使玩偶 | CDQ分治


    题目:

    南开OJ有非权限提交处

    http://oi.nks.edu.cn/zh/Problem/Details/2739


    题解:

    鹅鹅鹅....有三维(t,x,y),所以可以用CDQ解决的好题

    初始点就是t超级小的点

    先按x排个序,时间作为分治的第二维,这样只有前半段时间的修改操作对后半段时间的询问操作需要在当前solve处理,y作为需要用数据结构维护的第三维

    考虑把曼哈顿距离展开变成没有绝对值的式子,但是四种情况不好维护.

    如果以某一次询问的点(x0,y0)为源点,显然答案一定在四个象限中的一个

    考虑只维护第三象限的答案,那么绝对值式子可以变成(x0+y0)-(x+y)

    用树状数组可以维护y0位置之前的前缀最大值

    这样每次修改操作就在y位置插入(x+y)就可以做到维护位于第三象限的答案

    其他象限的答案我们只要旋转坐标轴变成第三象限即可

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 1000010
    #define INF 0x7fffffff
    using namespace std;
    int n,m;
    struct node
    {
        int id,op,x,y,pos;
        bool operator < (const node &b) const
        {
            if (x!=b.x) return x<b.x;
            if (y!=b.y) return y<b.y;
            return op<b.op;
        }
    }q[N],tmp[N];
    int ans[N],tot,t[2*N],lim=N;
    void insert(int x,int w)
    {
        for (;x<=lim;x+=x&-x) t[x]=max(t[x],w);
    }
    int query(int x)
    {
        int ret=0;
        for (;x;x-=x&-x)
        ret=max(ret,t[x]);
        return ret;
    }
    void clear(int x)
    {
        for (;x<=lim;x+=x&-x) t[x]=0;
    }
    void solve(int l,int r)
    {
        if (l==r) return ;
        int mid=l+r>>1;
        for (int i=l;i<=r;i++)
        {
        if (q[i].id<=mid && q[i].op==1)
            insert(q[i].y,q[i].y+q[i].x);
        if (q[i].id>mid && q[i].op==2)
        {
            int t=query(q[i].y);
            if (t!=0)
            ans[q[i].pos]=min(ans[q[i].pos],q[i].x+q[i].y-t);
        }
        }
        for (int k=l,i=l,j=mid+1;k<=r;k++)
        {
        if (q[k].id<=mid && q[k].op==1)
            clear(q[k].y);
        if (q[k].id<=mid) tmp[i++]=q[k];
        else tmp[j++]=q[k];
        }
        for (int i=l;i<=r;i++)
        q[i]=tmp[i];
        solve(l,mid);
        solve(mid+1,r);
        
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1,x,y;i<=n;i++)
        {
        scanf("%d%d",&x,&y);
        q[i]=(node){i,1,x+1,y+1,0};
        }
        for (int i=1,op,x,y;i<=m;i++)
        {
        scanf("%d%d%d",&op,&x,&y);
        if (op==1) q[i+n]=(node){i+n,1,x+1,y+1,0};
        else q[i+n]=(node){i+n,2,x+1,y+1,++tot},ans[tot]=INF;
        }
        sort(q+1,q+1+n+m); solve(1,n+m);
        for (int i=1;i<=n+m;i++) q[i].y=lim-q[i].y;
        sort(q+1,q+1+n+m);solve(1,n+m);
        for (int i=1;i<=n+m;i++) q[i].x=lim-q[i].x;
        sort(q+1,q+1+n+m);solve(1,n+m);
        for (int i=1;i<=n+m;i++) q[i].y=lim-q[i].y;
        sort(q+1,q+1+n+m);solve(1,n+m);
        for (int i=1;i<=tot;i++)
        printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    Linux监控平台、安装zabbix、修改zabbix的admin密码
    LVS DR模式搭建、keepalived+lvs
    负载均衡集群相关、LVS介绍、LVS调度算法、LVS NAT模式搭建
    集群相关、用keepalived配置高可用集群
    mysql基础
    MySQL主从、环境搭建、主从配制
    Tomcat配置虚拟主机、tomcat的日志
    Tomcat介绍、安装jdk、安装Tomcat、配置Tomcat监听80端口
    FTP相关、用vsftpd搭建ftp、xshell使用xftp传输文件、使用pure-ftpd搭建ftp服务
    HTTP Status 500
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8109361.html
Copyright © 2020-2023  润新知