zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    (IEEE-754) 字节数组与浮点数之间的互相转换(MODBUS float类型)
    C#中浮点数依IEEE-754标准转二进制串 (MODBUS 浮点数转换)
    SQL 向上取整、向下取整、四舍五入取整的实例!round、rounddown、roundup
    查看SQL SERVER数据库运行参数和连接数
    three.js 材质
    three.js 曲线
    three.js 几何体-组合网格
    three.js 几何体(三)
    three.js 几何体(二)
    three.js 几何体(一)
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8109361.html
Copyright © 2011-2022 走看看