zoukankan      html  css  js  c++  java
  • CF413E Maze 2D 线段树

    CF413E Maze 2D

    线段树


    题目
    宽度只有(1)的话怎么做?
    用线段树维护一下(dis)表示(l-r)区间的距离
    那么宽度为(2)的也一样啊
    就可以设四个距离
    表示左上到右上,左上到右下,左下到右上,左下到右下
    这样就可以查询了


    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2*1e5+10,inf=0x3f3f3f3f;
    int n,m,tu[10][maxn];
    struct tree{
    	int dt[5];//左上到右上 左上到右下 左下到右上 左下到右下
    }tr[maxn<<2];
    inline void pushup(int p){
    	tree ls=tr[p<<1],rt=tr[p<<1|1];
    	tr[p].dt[1]=min(inf,min(ls.dt[1]+rt.dt[1],ls.dt[2]+rt.dt[3])+1);
    	tr[p].dt[2]=min(inf,min(ls.dt[1]+rt.dt[2],ls.dt[2]+rt.dt[4])+1);
    	tr[p].dt[3]=min(inf,min(ls.dt[3]+rt.dt[1],ls.dt[4]+rt.dt[3])+1);
    	tr[p].dt[4]=min(inf,min(ls.dt[4]+rt.dt[4],ls.dt[3]+rt.dt[2])+1);
    	return;
    }
    void build(int p,int l,int r){
    	if(l==r){
    		tr[p].dt[1]=tr[p].dt[2]=tr[p].dt[3]=tr[p].dt[4]=inf;
    		if(tu[1][l]) tr[p].dt[1]=0;
    		if(tu[2][l]) tr[p].dt[4]=0;
    		if(tu[1][l] && tu[2][l]) tr[p].dt[2]=tr[p].dt[3]=1;
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    	pushup(p);
    }
    inline tree qry(int p,int l,int r,int x,int y){
    	if(x<=l && r<=y) return tr[p];
    	int mid=(l+r)>>1;
    	tree ls,rt,res;
    	bool fl1=0,fl2=0;
    	if(x<=mid) ls=qry(p<<1,l,mid,x,y),fl1=1;
    	if(mid<y) rt=qry(p<<1|1,mid+1,r,x,y),fl2=1;
    	if(fl1 && !fl2) return ls;
    	if(!fl1 && fl2) return rt;
    	res.dt[1]=min(inf,min(ls.dt[1]+rt.dt[1],ls.dt[2]+rt.dt[3])+1);
    	res.dt[2]=min(inf,min(ls.dt[1]+rt.dt[2],ls.dt[2]+rt.dt[4])+1);
    	res.dt[3]=min(inf,min(ls.dt[3]+rt.dt[1],ls.dt[4]+rt.dt[3])+1);
    	res.dt[4]=min(inf,min(ls.dt[4]+rt.dt[4],ls.dt[3]+rt.dt[2])+1);
    	return res;
    }
    inline int ask(int x,int y){
    	int a=(x-1)%n+1,b=(y-1)%n+1;
    	if(a>b){ swap(x,y);swap(a,b); }
    	tree xx=qry(1,1,n,a,b);
    	if(x<=n && y<=n) return xx.dt[1];
    	if(x<=n && y>n) return xx.dt[2];
    	if(x>n && y<=n) return xx.dt[3];
    	if(x>n && y>n) return xx.dt[4];
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=2;i++){
    		string s;cin>>s;
    		for(int j=0;j<n;j++) if(s[j]=='.') tu[i][j+1]=1;
    	}
    	build(1,1,n);
    	while(m--){
    		int x,y;scanf("%d%d",&x,&y);
    		int ans=ask(x,y);
    		if(ans>=inf) printf("-1
    ");
    		else printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    SharePoint研究之表单登录配置
    asp.net自定义控件之加载层
    可替换参数在SharePoint和VS中的使用
    C#树类型及其遍历
    Asp.net下拉树实现(Easy UI ComboTree)
    驾校考试科目三心得
    c#pdf查看器
    jquery获取服务器控件Label的值
    [JLOI2014] 松鼠的新家 (lca/树上差分)
    洛谷P1445 [Violet] 樱花 (数学)
  • 原文地址:https://www.cnblogs.com/ChrisKKK/p/11743871.html
Copyright © 2011-2022 走看看