• 【维护】【线段树】CF413E Maze 2D


    【维护】【线段树】CF413E Maze 2D

    题目大意

    image

    给定一个\(2\times n\) 的矩阵,黄色方格代表不能通行,蓝色格子代表畅通无阻,同时对每一个方格进行编号,求编号为x到编号为y的最短路。

    思路

    先不考虑是具体地从哪里到哪里,而是先进行一个笼统地分析。

    单单去考虑从第i行到第j行的最短路。

    一共有四种方案:

    1. 左上角到右上角uu
    2. 左上角到右下角ud
    3. 左下角到右上角du
    4. 左下角到右下角dd

    而这就是我们需要进行维护的数据

    struct data{
        int d1,d2,d3,d4;
    }
    

    初始化和合并

    image

    当考虑长度为1的区间的时候,左上角和右上角是重叠的,左下角和右下角是重叠的。

    image

    要得到区间为1到9的数据我们只需知道区间1到5的信息和区间6到9的信息。

    比如要求得区间1到9从左上角到右上角的最短路。

    我们有两种走法

    一种是从区间1到5的左上角走到其右上角,再接着从区间6到9的左上角走到区间6到9的右上角。

    另外一种是从区间1到5的左上角走到其右下角,再接着从区间6到9的左下角走到区间6到9的右上角。

    Code

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    using namespace std;
    const int N = 2E5+500,inf = 8e5+500;
    int n,m;
    struct Data{
    	int uu,ud,du,dd;
    };
    struct Seg_Tree{
    	int l,r;
    	Data data;
    }tr[N<<2];
    bool maze[2][N];
    
    Data merge(Data x,Data y)
    {
        Data temp = {inf,inf,inf,inf};
    	temp.uu = min(inf, min( x.ud+y.du+1 , x.uu+y.uu+1 ) );
    	temp.ud = min(inf, min( x.ud+y.dd+1 , x.uu+y.ud+1 ) );
    	temp.du = min(inf, min( x.dd+y.du+1 , x.du+y.uu+1 ) );
    	temp.dd = min(inf, min( x.dd+y.dd+1 , x.du+y.ud+1 ) );
    	return temp;
    }
    
    void build(int u,int l,int r)
    {
    	if(l==r)
    	{
    		tr[u].data = {inf,inf,inf,inf};
    		if(maze[0][l]) tr[u].data.uu = 0;
    		if(maze[1][l]) tr[u].data.dd = 0;
    		if(maze[0][l]&&maze[1][l]) tr[u].data.du = tr[u].data.ud = 1; 
    	    return ;
    	}
    	int mid = l + r >> 1 ;
    	build(u<<1,l,mid);
    	build(u<<1|1,mid+1,r);
    	tr[u].data = merge(tr[u<<1].data,tr[u<<1|1].data);
    }
    
    Data query(int u,int l,int r,int x,int y)
    {
    	if(x<=l&&r<=y)
    	   return tr[u].data;
    	int mid = l + r >> 1;
    	if(mid>=y) return query(u<<1,l,mid,x,y);
    	if(mid+1<=x) return query(u<<1|1,mid+1,r,x,y);
    	return merge( query(u<<1,l,mid,x,y) , query(u<<1|1,mid+1,r,x,y) );
    }
    
    int ask(int x,int y)
    {
    	int rowx = (x>=n+1) + 1 , rowy = (y>=n+1) + 1;
    	int colx = x-(rowx==2?n:0) , coly = y-(rowy==2?n:0);
    	if(colx>coly) swap(colx,coly),swap(rowx,rowy);
    	Data ans = query(1,1,n,colx,coly);
    	int res;
    	if(rowx==1&&rowy==1) res = ans.uu;
    	else if(rowx==1&&rowy==2) res = ans.ud;
    	else if(rowx==2&&rowy==1) res = ans.du;
    	else if(rowx==2&&rowy==2) res = ans.dd;
        if(res==inf) return -1;
        return res;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>m;
        for(int i=0;i<=1;i++)
        {
        	string s;
        	cin>>s;
        	for(int j=0;j<s.length();j++)
        	   if(s[j]=='.') maze[i][j+1] = 1;
    	}
    	build(1,1,n);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		cout<<ask(x,y)<<endl;
    	}
        return 0;
    }
    
    
  • 相关阅读:
    音频编辑大师 3.3 注冊名 注冊码
    Cocos2d_x的特点及环境配置
    strcpy_s与strcpy的比較
    Android Bundle类
    DB9 公头母头引脚定义及连接
    80x86汇编小站站长简单介绍
    腾讯webqq最新password加密算法,hash算法
    八大排序算法总结
    xpage 获取 附件
    转基因大豆提高大豆油脂产量80%
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15929168.html
Copyright © 2020-2023  润新知