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
原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14107015.html