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
  • 相关阅读:
    .Netcore 2.0 Ocelot Api网关教程(7)- 限流
    .Netcore 2.0 Ocelot Api网关教程(6)- 配置管理
    .Netcore 2.0 Ocelot Api网关教程(5)- 认证和授权
    .Netcore 2.0 Ocelot Api网关教程(4)- 服务发现
    字符串方法集锦
    location下的属性集锦
    Js apply call方法详解
    所有事件event集锦
    移动端常用默认样式
    原生js的各种方法
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14107015.html
Copyright © 2011-2022 走看看