洛谷题面传送门

发篇正常点的题解。

首先对于这样的题暴力枚举肯定是不行的,因为最小时间显然可能达到 \((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. JuiceFS 如何帮助趣头条超大规模 HDFS 降负载

    作者简介 王振华,趣头条大数据总监,趣头条大数据负责人. 王海胜,趣头条大数据工程师,10 年互联网工作经验,曾在 eBay.唯品会等公司从事大数据开发相关工作,有丰富的大数据落地经验. 高昌健,Ju ...

  2. Noip模拟70 2021.10.6

    T1 暴雨 放在第一道的神仙题,不同的做法,吊人有的都在用线段树维护$set$预处理 我是直接$dp$的,可能代码的复杂度比那种的稍微小一点 设$f[i][j][p][0/1]$表示考虑了前$i$列, ...

  3. Linux C语言多线程编程实例解析

    Linux系统下的多线程遵循POSIX线程接口,称为 pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.顺便说一下,Linux ...

  4. 字符串匹配 ?kmp : hash

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...

  5. 『学了就忘』Linux基础命令 — 18、Linux命令的基本格式

    目录 1.命令提示符说明 2.命令的基本格式 (1)举例ls命令 (2)说明ls -l命令的 输出内容 1.命令提示符说明 [root@localhost ~] # []:这是提示符的分隔符号,没有特 ...

  6. pvcreate vgcreate lvcreate 扩容

    centos6 服务器磁盘扩容 1.创建物理卷 /dev/sdb #pvcreate /dev/sdb 参数:/dev/sdb 设备名 2.创建卷组 vg_02 #vgcreate  vg_02  / ...

  7. LoadRunner12回放与录制

    系统版本 本人的操作系统是win10 版本是loadrunner12. 开启loadrunner自带的机票预订服务器 找到loadrunner自带的机票预订测试服务器下图中点击启动 如下图所示代表启动 ...

  8. pip 常用命令小结

    pip 常用命令小结 pip这个工具我们经常会用到,毕竟python 是一门以第三方库庞大而著名的编程语言,所以我们总会用pip 安装一些依赖库,当然这只是pip 最常用的一个命令,下面就来介绍一下 ...

  9. 好久没更新了,我回来了---Ajax

    1.Ajax概念以及优势 * 什么是AJAX * AJAX(Asynchronous JavaScript And XML),(异步 JavaScript 和 XML),中文名:阿贾克斯.是指一种创建 ...

  10. 【完虐算法】LeetCode 接雨水问题,全复盘

    大家好! 动态规划题目是总结的比较完整了.下面是自从和大家刷开题总结的动态规划解题方法. 今年全国夏天雨是真的多,突然想到今年北京的夏天也不像往年那么热.不知不觉就稳稳地度过了夏天来到秋天. 恰巧前几 ...