题解:CF1733E Conveyor

· · 题解

CF1733E Conveyor

(古早以前的每周讲题报的题目,结果不讲了,想起来交个题解。)

一道很有意思的人类智慧题。

因为 t 很大,直接求 (x,y) 有没有史莱姆是不现实的。

传送带每经过一只史莱姆就转一次方向,可以发现传送带是“右下右下……” 这样来的。

所以假设经过 (x,y) 的史莱姆有 z 只,那就有 \lceil\frac{z}{2}\rceil 只向右走,\lfloor\frac{z}{2}\rfloor 只向下走(第一只史莱姆向右走)。

可以设 f_{t,x,y}t 时刻之内经过 (x,y) 的史莱姆数量。

那么当 f_{t,x,y}-f_{t-1,x,y} 为正数时,t 时刻一定有史莱姆经过。

告诉了总时间,那史莱姆数量可以算出来,只需要注意一下新出生的史莱姆在给定的时间内能不能走到询问的位置了。 单次询问复杂度 $O(n^2)$。 史莱姆,可爱捏。 ```cpp void solve() { memset(f1,0,sizeof f1),memset(f2,0,sizeof f2); t=read(),x=read(),y=read(); f1[0][0]=t-x-y+1,f2[0][0]=t-x-y;//t-x-y+1 时刻起,新出生的史莱姆 t 秒走不到 (x,y)。t-x-y 同理 for(int i=0;i<=x;i++) for(int j=0;j<=y;j++) { if(i) f1[i][j]+=f1[i-1][j]/2,f2[i][j]+=f2[i-1][j]/2;//从上面转移 if(j) f1[i][j]+=(f1[i][j-1]+1)/2,f2[i][j]+=(f2[i][j-1]+1)/2;//从左边转移 } puts(f1[x][y]>f2[x][y]?"YES":"NO"); } ```