zoukankan      html  css  js  c++  java
  • P4739 [CERC2017]Donut Drone

    Description

    You are building a simulation in which a drone explores a volatile torus-shaped planet. Technically,the drone is moving across a toroidal grid — a rectangular grid that wraps around circularly in both dimensions. The grid consists of cells organized into $r$ rows numbered $1$ through $r$ top to bottom and $c$
    columns numbered $1$ through $c$ left to right. Each grid cell has a certain elevation — a positive integer.

    The drone is initially located in the cell in the first row and first column. In each step the drone considers three cells: the cell directly to the right, the cell diagonally right-down and the cell diagonally right-up (wrapping around if necessary). The drone flies to the cell with the largest elevation of the three.

    Two types of events may happen during the simulation:
    - “``move k``” — The drone makes $k$ steps.
    - “``change a b e``” — The elevation of the cell in row $a$ column $b$ changes to $e$.

    Find the drone’s position immediately after each ``move`` event. You may assume that at each point in time, no sequence of three circularly consecutive cells in the same column will have the same elevation.
    Hence, each drone step is well defined.

    Solution

    先暴力求出每一个点的最优决策

    在用线段树维护一下跳过某段区间的最优决策,最终1节点维护的就是跳过一圈之后的位置

    可以把每次跳跃分成数圈和两个不完整的圈,不完整的暴力跳,完整的用倍增

    修改时因为只修改一个点,所以在线段树上也是单调修改

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int R,C,map[2005][2005],ans[2005][2005],f[2005][31],nx=1,ny=1;
    char str[15];
    struct Tree
    {
        int val[2005];
    }tr[8005];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return f*w;
    }
    void solve(int &x,int &y)
    {
        int x1=x==1?R:x-1,x2=x,x3=x==R?1:x+1,maxx=0;
        y=y==C?1:y+1;
        if(map[x1][y]>maxx) maxx=map[x1][y],x=x1;
        if(map[x2][y]>maxx) maxx=map[x2][y],x=x2;
        if(map[x3][y]>maxx) maxx=map[x3][y],x=x3;
    }
    void pushup(int i)
    {
        for(int j=1;j<=R;j++) tr[i].val[j]=tr[i<<1|1].val[tr[i<<1].val[j]];
    }
    void build(int i,int l,int r)
    {
        if(l==r)
        {
            for(int j=1;j<=R;j++) tr[i].val[j]=ans[l][j];
            return;
        }
        int mid=l+r>>1;
        build(i<<1,l,mid),build(i<<1|1,mid+1,r);
        pushup(i);
    }
    void update(int i,int l,int r,int pos)
    {
        if(l==r)
        {
            for(int j=1;j<=R;j++) tr[i].val[j]=ans[l][j];
            return;
        }
        int mid=l+r>>1;
        if(pos<=mid) update(i<<1,l,mid,pos);
        else update(i<<1|1,mid+1,r,pos);
        pushup(i);
    }
    int main()
    {
        R=read(),C=read();
        for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) map[i][j]=read();
        for(int i=1;i<=R;i++) for(int j=1;j<=C;j++)
        {
            int x=i,y=j;
            solve(x,y),ans[j][i]=x;
        }
        build(1,1,C);
        for(int i=1;i<=R;i++) f[i][0]=tr[1].val[i];
        for(int i=1;i<=30;i++) for(int j=1;j<=R;j++) f[j][i]=f[f[j][i-1]][i-1];
        for(int m=read();m;m--)
        {
            scanf("%s",str);
            if(str[0]=='m')
            {
                int k=read();
                while(k&&ny!=1) solve(nx,ny),--k;
                for(int i=30;i;i--) if(1ll*k>=1ll*C*(1<<i)) k-=C*(1<<i),nx=f[nx][i];
                while(k>0) solve(nx,ny),--k;
                printf("%d %d
    ",nx,ny);
            }
            else
            {
                int a=read(),b=read(),e=read(),dy=b==1?C:b-1;
                map[a][b]=e;
                for(int i=1;i<=R;i++)
                {
                    int x=i,y=dy;
                    solve(x,y),ans[dy][i]=x;
                }
                update(1,1,C,dy);
                for(int i=1;i<=R;i++) f[i][0]=tr[1].val[i];
                for(int i=1;i<=30;i++) for(int j=1;j<=R;j++) f[j][i]=f[f[j][i-1]][i-1];
            }
        }
        return 0;
    }
    [CERC2017]Donut Drone
  • 相关阅读:
    函数的命名空间和作用域
    python 各个地方导航(方便查询,持续更新!)
    零基础学虚幻4(UE4):蓝图+VR 丁树凯教程
    UE4打包后的游戏,无法打卡其他关卡的解决办法
    【精辟】进制转换
    Git仓库的初始化
    【编程】杂碎知识点
    MFC制作带界面的DLL库
    StartImage.DLL使用说明
    MFC对话框程序:实现程序启动画面
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14107015.html
Copyright © 2011-2022 走看看