[题解]codeforces413e Maze 2D

题目:戳这里
题目大意:
给定一个 2n 的地图,某些地方是障碍,只能上下左右走,多组询问两点直接的距离。 n2105

Solution

线段树维护区间左上到右上、左下到右上、左上到右下、左下到右下的最小距离和区间两端的四个格子是否是障碍即可。合并的时候稍微有点麻烦。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

template<typename T>inline void read(T &x){
    T f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    x*=f;
}

typedef long long LL;
const int maxn=200010,inf=0x7fffffff;
int n,m;
char str[2][maxn];
struct Data{
    LL dis[2][2];
    Data(){memset(dis,0,sizeof dis);}
};
Data operator+(Data l,Data r){
    Data x;
    x.dis[0][0]=min(l.dis[0][0]+r.dis[0][0],l.dis[0][1]+r.dis[1][0])+1;
    x.dis[1][1]=min(l.dis[1][1]+r.dis[1][1],l.dis[1][0]+r.dis[0][1])+1;
    x.dis[0][1]=min(l.dis[0][0]+r.dis[0][1],l.dis[0][1]+r.dis[1][1])+1;
    x.dis[1][0]=min(l.dis[1][0]+r.dis[0][0],l.dis[1][1]+r.dis[1][0])+1;
    return x;
}

struct Segment_Tree{
    #define lc x<<1
    #define rc x<<1|1
    Data T[maxn<<2];
    int L[maxn<<2],R[maxn<<2];
    Segment_Tree(){
        memset(L,0,sizeof L);
        memset(R,0,sizeof R);
    }
    void Build(int x,int l,int r){
        if((L[x]=l)==(R[x]=r)){
            T[x].dis[0][1]=T[x].dis[1][0]=1;T[x].dis[0][0]=T[x].dis[1][1]=0;
            if(str[0][l]=='X')T[x].dis[0][0]=T[x].dis[0][1]=T[x].dis[1][0]=inf;
            if(str[1][l]=='X')T[x].dis[1][1]=T[x].dis[0][1]=T[x].dis[1][0]=inf;
            return;
        }
        int mid=(l+r)>>1;
        Build(lc,l,mid);Build(rc,mid+1,r);
        T[x]=T[lc]+T[rc];
    }
    Data Query(int x,int l,int r){
        if(L[x]>=l&&R[x]<=r)return T[x];
        int mid=(L[x]+R[x])>>1;
        Data temp;
        if(l<=mid&&r>mid)temp=Query(lc,l,r)+Query(rc,l,r);
        else if(l<=mid)temp=Query(lc,l,r);
        else temp=Query(rc,l,r);
        return temp;
    }
}tree;

int main(){
    read(n);read(m);
    scanf("%s%s",str[0]+1,str[1]+1);
    tree.Build(1,1,n);
    while(m--){
        int u,v;
        bool f=false,g=false;
        read(u);read(v);
        if(u>n)u-=n,f=true;
        if(v>n)v-=n,g=true;
        if(u>v)swap(u,v),swap(f,g);
        if(u==v)printf("%d\n",f^g);
        else{
            Data temp=tree.Query(1,u,v);
            printf("%lld\n",temp.dis[f][g]>=inf?-1:temp.dis[f][g]);
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
美赛e题通常会要求解决一个实际的工程或管理问题,涉及到建模、数据分析、优化等方面。解题思路通常分为以下几个步骤: 1. 问题理解:首先要仔细阅读题目,理解问题背景、要求和限制条件。明确问题的目标和约束条件是解题的第一步。 2. 建立数学模型:根据问题要求和数据,建立合适的数学模型来描述问题。可能涉及到微积分、概率统计、线性代数等数学知识。模型的建立需要考虑到实际情况和假设条件,尽量简化和抽象问题方便求解。 3. 数据分析:根据所给数据或者自行获取数据,进行数据的处理和分析。可能需要进行数据清洗、统计分析、可视化等工作,以便更好地理解问题和验证模型。 4. 求解优化问题:根据建立的数学模型,可以采用各种优化方法来求解问题。常用的方法包括线性规划、整数规划、动态规划、遗传算法等。在求解的过程中需要注意约束条件的处理和结果的解释。 5. 结果分析和验证:得到结果后,需要进行结果的分析和验证,看是否符合实际情况和问题要求。如果有必要,可以进行灵敏度分析和稳定性分析,探讨模型的鲁棒性和可靠性。 6. 方案优化和改进:根据结果分析的情况,可以对建模和求解过程进行改进和优化,以提高解题的精度和效率。 以上是美赛e题解题思路的一般流程,具体问题具体分析,需要根据具体问题的特点来灵活应对。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值