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
  • 相关阅读:
    APK自我保护方法
    Andorid APK反逆向解决方案---梆梆加固原理探寻
    判断android文件是否加壳
    java调用dll-JNA
    Java调用本地接口
    pat00-自测2. 素数对猜想 (20)
    pat00-自测4. Have Fun with Numbers (20)
    pat00-自测3. 数组元素循环右移问题 (20)
    pat00-自测1. 打印沙漏(20)
    pat1013. Battle Over Cities (25)
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14107015.html
Copyright © 2011-2022 走看看