洛谷题面传送门

发篇正常点的题解。

首先对于这样的题暴力枚举肯定是不行的,因为最小时间显然可能达到 \((4nm)^5\approx 10^{20}\),就算数据很难卡到这个上界,构造出一些使你暴力超时的数据还是很容易的,因此考虑一些不基于暴力枚举的做法。不难发现,对于每个细菌而言,如果它的位置及方向已经确定了,那么它下一步所在的位置及面对的方向也已经确定了,也就是说,如果我们对于每个细菌,把位置及方向看作一个三元组 \((x,y,d)\),并且在一步可达的三元组之间连有向边,那么可以得到 \(k\) 个基环内向森林。而由于得到的图是基环内向森林,对于一个点,从它出发可以到达的点应是一个 \(\rho\) 形。而对于陷阱格 \((x,y)\),到达陷阱格即意味着在建好的图上到达 \((x,y,0),(x,y,1),(x,y,2),(x,y,3)\) 中的一个点,因此题目可以转化为:

  • 求最小的时间 \(t\),满足对于全部全部 \(k\) 个基环内向森林的起点,走 \(t\) 步后到达的点都是 \((x,y,0),(x,y,1),(x,y,2),(x,y,3)\) 中的一个

由于此题 \(k\) 很小,因此我们考虑暴力 \(4^k\) 枚举每个细菌的终点 \((x,y,d_i)\),那么问题可进一步转化为,最少需要多少时间 \(t\),满足每个细菌走 \(t\) 步后到达的点都恰好是 \((x,y,d_i)\)。我们对于每个细菌 \(i\),预处理出以下四个量:

  • \(mn_i\):从该细菌起点对应的三元组开始,最少走多少步可以走到环上
  • \(len_i\):从该细菌起点对应的三元组开始,能够走到的 \(\rho\) 字形的环长
  • \(typ_{i,d}\):对于终点 \((x,y,d)\),它在不在该细菌对应的起点能够走到的 \(\rho\) 字形的环上
  • \(tim_{i,d}\):对于终点 \((x,y,d)\),最少需要多少时间才能从细菌 \(i\) 起点对应的三元组走到 \((x,y,d)\)

那么显然如果存在一个 \((x,y,d_i)\) 无法从 \(i\) 的起点到达那么就不存在这样的 \(i\),否则继续分类讨论:如果存在一个 \((x,y,d_i)\) 不在细菌 \(i\) 的起点对应的环上,那么显然时间必须为 \(tim_{i,d_i}\),因为错过这个点就无法再回来了,我们只需检验从所有细菌的起点开始走 \(T=tim_{i,d_i}\) 步是否能够到达对应的终点即可,如果都能那么就用 \(T\) 更新答案,否则不做处理。具体检验方法就是如果 \(typ_{i,d_i}=1\),那么必须有 \(T\ge mn_i\) 且 \(T\equiv tim_{i,d_i}\pmod{len_i}\),否则必须有 \(tim_{i,d_i}=T\),存在 \(typ_{i,d_i}=0\) 的情况都判完了,剩余的就是 \(typ_{i,d_i}\) 都为 \(1\) 的情况了。对于每个细菌 \(i\),显然它在 \(T\) 时刻到达 \((x,y,d_i)\) 的充要条件是 \(T\ge mn_i\) 且 \(T\equiv tim_{i,d_i}\pmod{len_i}\)。我们如果只考虑后一个条件,那显然就是一个解同余方程组的问题,exCRT 合并即可,加了第一个条件,由于方程组的通解可以写成 \(T=T_0+kT'\) 的形式,因此我们对于每个细菌求出 \(k\) 最少需要是多少才能满足第一个限制,然后取个 \(\max\) 即可。

复杂度大概是 \(4^kk\log T+nmk\),跑得飞快,最慢的一个点只用了 6ms

u1s1 这题上界是 \(10^{20}\),但实测把 INF 开到 \(9\times 10^{18}\) 能过……

const int MAXN=50;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
int n,m,k,X,Y,id[1<<7];
int getid(int x,int y,int d){return d*n*m+(x-1)*m+y;}
pair<pii,int> getcor(int x){return mp(mp((x-1)%(n*m)/m+1,(x-1)%m+1),(x-1)/n/m);}
int a[7][MAXN+5][MAXN+5],st[7];
int getnxt(int t,int x,int y,int d){
d=(d+a[t][x][y])&3;
if(x+dx[d]<1||x+dx[d]>n||y+dy[d]<1||y+dy[d]>m)
d^=2;
return getid(x+dx[d],y+dy[d],d);
}
vector<int> rch[7];
int stk[MAXN*MAXN*4+5],tp=0,len[7];
bool vis[MAXN*MAXN*4+5];
void dfs(int t,int x){
if(vis[x]){
for(int i=1;i<=tp;i++) rch[t].pb(stk[i]);
for(int i=1;i<=tp;i++) if(stk[i]==x) len[t]=tp-i+1;
return;
} vis[x]=1;pair<pii,int> p=getcor(x);stk[++tp]=x;
dfs(t,getnxt(t,p.fi.fi,p.fi.se,p.se));
}
int need[7][5],typ[7][5];
ll gcd(ll x,ll y){return (!y)?x:gcd(y,x%y);}
void exgcd(ll x,ll y,ll &a,ll &b){
if(!y) return a=1,b=0,void();exgcd(y,x%y,a,b);
ll tmp=a;a=b;b=tmp-(x/y)*b;
}
ll smul(ll x,ll y,ll mod){
x=(x%mod+mod)%mod;y=(y%mod+mod)%mod;ll res=0;
for(;y;y>>=1,x=(x+x)%mod) if(y&1) res=(res+x)%mod;
return res;
}
pair<ll,ll> combine(ll a1,ll b1,ll a2,ll b2){
if(!~a1||!~a2) return mp(-1,-1);
ll d=gcd(a1,a2);if((b2-b1)%d) return mp(-1,-1);
ll t=(b2-b1)/d;ll k1,k2;exgcd(a1,a2,k1,k2);
k1=smul(k1,t,a2/d);ll A=a1/d*a2;
return mp(A,(smul(a1,k1,A)+b1)%A);
}
int main(){
scanf("%d%d%d%d%d",&n,&m,&k,&X,&Y);
id['U']=0;id['R']=1;id['D']=2;id['L']=3;
for(int i=1;i<=k;i++){
int x,y;char c;cin>>x>>y>>c;
st[i]=getid(x,y,id[c]);
for(int j=1;j<=n;j++) for(int l=1;l<=m;l++)
scanf("%1d",&a[i][j][l]);
}
for(int i=1;i<=k;i++){
memset(vis,0,sizeof(vis));tp=0;
dfs(i,st[i]);
// for(int x:rch[i]) printf("%d\n",x);
for(int d=0;d<4;d++){
int x=getid(X,Y,d),ps=-1;
for(int j=0;j<rch[i].size();j++) if(rch[i][j]==x) ps=j;
need[i][d]=ps;typ[i][d]=(ps>=rch[i].size()-len[i]);
// printf("%d %d %d %d %d\n",i,d,x,need[i][d],typ[i][d]);
}
} ll res=9e18;
for(int i=0;i<(1<<(k<<1));i++){
bool flg=1;
for(int j=1;j<=k;j++){
int x=i>>((j-1)<<1)&3;
if(!~need[j][x]) flg=0;
} if(!flg) continue;
int tim=-1;
for(int j=1;j<=k;j++){
int x=i>>((j-1)<<1)&3;
if(!typ[j][x]) tim=need[j][x];
}
if(~tim){
for(int j=1;j<=k;j++){
int x=i>>((j-1)<<1)&3;
if(!typ[j][x]&&need[j][x]!=tim) flg=0;
if(typ[j][x]&&(tim<rch[j].size()-len[j]||tim%len[j]!=need[j][x]%len[j]))
flg=0;
} if(flg) chkmin(res,tim);
continue;
}
pair<ll,ll> A=mp(1,0);
for(int j=1;j<=k;j++){
int x=i>>((j-1)<<1)&3;
A=combine(A.fi,A.se,len[j],need[j][x]%len[j]);
} if(!~A.fi) continue;ll tt=A.se;
for(int j=1;j<=k;j++){
int x=i>>((j-1)<<1)&3;
if(A.se<need[j][x]) chkmax(tt,A.se+(need[j][x]-A.se+A.fi-1)/A.fi*A.fi);
} chkmin(res,tt);
} printf("%lld\n",(res==9e18)?-1:(res+1));
return 0;
}

洛谷 P4621 - [COCI2012-2013#6] BAKTERIJE(exCRT)的更多相关文章

  1. 洛谷 P1979 [ NOIP 2013 ] 华容道 —— bfs + 最短路

    题目:https://www.luogu.org/problemnew/show/P1979 真是一道好题... 首先考虑暴力做法,应该是设 f[i][j][x][y] 记录指定棋子和空格的位置,然后 ...

  2. 洛谷P4774 BZOJ5418 LOJ2721 [NOI2018]屠龙勇士(扩展中国剩余定理)

    题目链接: 洛谷 BZOJ LOJ 题目大意:这么长的题面,就饶了我吧emmm 这题第一眼看上去没法列出同余方程组.为什么?好像不知道用哪把剑杀哪条龙…… 仔细一看,要按顺序杀龙,所以获得的剑出现的顺 ...

  3. 扩展中国剩余定理学习笔记+模板(洛谷P4777)

    题目链接: 洛谷 题目大意:求同余方程组 $x\equiv b_i(mod\ a_i)$ 的最小正整数解. $1\leq n\leq 10^5,1\leq a_i\leq 10^{12},0\leq ...

  4. 【题解】洛谷P1967 [NOIP2013TG] 货车运输(LCA+kruscal重构树)

    洛谷P1967:https://www.luogu.org/problemnew/show/P1967 思路 感觉2013年D1T3并不是非常难 但是蒟蒻还是WA了一次 从题目描述中看出每个点之间有许 ...

  5. 洛谷 P3375 【模板】KMP字符串匹配

    我这段时间因为字符串太差而被关了起来了(昨晚打cf不会处理字符串现场找大佬模板瞎搞,差点就凉了),所以决定好好补一下字符串的知识QAQ,暂时先学习kmp算法吧~ 题目链接:https://www.lu ...

  6. 洛谷 P5345: 【XR-1】快乐肥宅

    题目传送门:洛谷 P5345. 很荣幸为 X Round 1 贡献了自己的一题. 题意简述: 给定 \(n\) 组 \(k_i,g_i,r_i\)(\(0\le k_i,r_i<g_i\le 1 ...

  7. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  8. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  9. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

随机推荐

  1. Python语法2

    目录 选择结构 循环结构 文件读写 函数 类和对象 选择结构 if,elif,else,使用时注意条件的先后顺序 通过缩进四个空格来区分代码块 # 从控制台输入 age = int(input(&qu ...

  2. JVM:内存模型

    JVM:内存模型 说明:这是看了 bilibili 上 黑马程序员 的课程 JVM完整教程 后做的笔记 1. java 内存模型 很多人将[java 内存结构]与[java 内存模型]傻傻分不清,[j ...

  3. 零基础学习Linux必会的60个常用命令

    Linux必学的60个命令Linux提供了大量的命令,利用它可以有效地完成大量的工 作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令. ...

  4. word-break leetcoder C++

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  5. 手把手教你学Dapr - 4. 服务调用

    上一篇:手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 介绍 通过使用服务调用,您的应用程序可以使用标准的gRPC或HTTP协议与其他应用程序可靠.安全地通信. 为什么不直接用Ht ...

  6. Forest v1.5.12 发布,声明式 HTTP 框架,已超过 1.6k star

    Forest介绍 Forest 是一个开源的 Java HTTP 客户端框架,它能够将 HTTP 的所有请求信息(包括 URL.Header 以及 Body 等信息)绑定到您自定义的 Interfac ...

  7. 二层组网AP上线

    一.实验目的 1)掌握配置WLAN源接口的命令 2)掌握配置DHCP服务器的命令 3)掌握手工确认AP上线的方法a 二.实验仪器设备及软件 仪器设备:一台AC,四台AP 软件:ENSP 三.实验原理 ...

  8. Tomcat 内存马(二)Filter型

    一.Tomcat处理请求 在前一个章节讲到,tomcat在处理请求时候,首先会经过连接器Coyote把request对象转换成ServletRequest后,传递给Catalina进行处理. 在Cat ...

  9. 【完美解决】IDEA 中 Maven 报错 Cannot resolve xxx 和 Maven 中 Dependencies 报红/报错。

    目录 前提 场景 解决办法 1.首先,清除缓存,点击之后重启IDEA. 2.关闭IDEA,打开项目文件夹 3.重新打开 IDEA,找到右边的 Maven 4.解决 Maven 中 Dependenci ...

  10. C语言图书管理借阅系统——ncurses库的使用

    一.前言 作为一只大四狗,最近还跟着大二同学修了一门课(当然不是之前没通过啦),课程是高级语言课程设计,高级语言指的是C语言 :),内容是做一个XX管理系统,我选择了图书管理系统,先介绍下我做的系统: ...