CF413E 题解
题意简述
有一个
题目分析
虽然没有修改,但是用线段树维护答案可能会更直观、清晰一些。
用线段树的每个结点维护第
两个结点答案的合并也比较简单:对
代码实现
#include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f;//最大值表示不可达 int n,q,l,r,ans; char op1[200010],op2[200010]; struct node { int l,r; int mn[2][2];//两维分别是左和右,0 代表上,1 代表下。 friend node operator +(node a,node b)//合并 { node c; memset(c.mn,0x3f,sizeof c.mn);//初始化最大值 c.l=a.l,c.r=b.r; for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++)//枚举中间是从哪行走 c.mn[i][j]=min(c.mn[i][j],a.mn[i][k]+b.mn[k][j]+1); //答案取 min(注意从左结点到右结点时步数要再 +1) return c; } }tr[800010]; void pushup(int p) { tr[p]=tr[p<<1]+tr[p<<1|1]; }//左右子结点更新父节点 void build(int p,int l,int r) { tr[p].l=l,tr[p].r=r; if(l==r) { tr[p].mn[0][0]=(op1[l]=='.'?0:INF); tr[p].mn[1][1]=(op2[l]=='.'?0:INF);//如果能走就是 0,否则不可达 tr[p].mn[0][1]=(op1[l]=='.'&&op2[l]=='.'?1:INF); tr[p].mn[1][0]=(op1[l]=='.'&&op2[l]=='.'?1:INF);//如果能走就是 1,否则不可达 return; } int mid=l+r>>1; build(p<<1,l,mid);//建左子结点 build(p<<1|1,mid+1,r);//建右子结点 pushup(p); } node query(int p,int l,int r)//为了方便,直接返回整个结构体。 { if(tr[p].l>=l&&tr[p].r<=r) return tr[p];//全覆盖就直接返回。 int mid=tr[p].l+tr[p].r>>1; if(mid<l) return query(p<<1|1,l,r);//只涉及右子结点 else if(mid>=r) return query(p<<1,l,r);//只涉及左子结点 else return query(p<<1,l,r)+query(p<<1|1,l,r);//左右子结点都涉及,合并一下 } int main() { scanf("%d%d%s%s",&n,&q,op1+1,op2+1); build(1,1,n); while(q--) { scanf("%d%d",&l,&r); if((l%n?l%n:n)>(r%n?r%n:n))//注意 n 在上行,2n 在下行 swap(l,r); printf("%d\n",(ans=query(1,(l%n?l%n:n),(r%n?r%n:n)).mn[(l-1)/n][(r-1)/n])==INF?-1:ans);//注意最大值是不可达,输出 -1 } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!