• 【线段树】bzoj1018 [SHOI2008]堵塞的交通traffic


    线段树的每个叶子节点存一列。

    每个节点维护六个域,分别是左上左下、左上右上、左上右下、左下右上、左下右下、右上右下在区间内部的连通性,不考虑绕出去的情况。

    初始每个叶子的左上左下、右上右下是连通的。

    每次修改纵列时,直接去线段树里修改。

    每次修改横行时,将其左右两列全都pushup一遍。

    具体怎么维护,并不难,请自行思考。

    每次询问时,提取出来[1,l-1],[l,r],[r+1,n]的连通性,然后讨论是否绕出来的情况。

    不推荐使用循环维护,人工讨论反而更加方便。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 100001
    int n;
    bool heng[2][N];/*heng(i,j)±íʾ(i,j)ºÍ(i+1,j)Ö®¼äÊÇ·ñÓбß*/
    bool zong[N];/*zong(i)±íʾ(0,i)ºÍ(1,i)Ö®¼äÊÇ·ñÓбß*/
    struct Node{bool zszx,zsys,zsyx,zxys,zxyx,ysyx;}T[N<<2];
    /*!!!ÐèÒªµ¥¶ÀÌÖÂÛµ¥¸ö×ÝÁкÍÆäËûµÄºÏ²¢µÄÇé¿ö!!!...ºÃ°ÉÆäʵ²»ÓÃ...³õʼʱÿ¸ö×ÝÁеÄzsys,zxyx=1*/
    inline void pushup(Node &rt,const Node &ls,const Node &rs,const int &r1)
    {
    	if(ls.zszx) rt.zszx=1;//zszx
    	else if(ls.zsys && rs.zszx && ls.zxyx && heng[0][r1] && heng[1][r1]) rt.zszx=1;
    	else rt.zszx=0;
    	if(rs.ysyx) rt.ysyx=1;//ysyx
    	else if(rs.zsys && ls.ysyx && rs.zxyx && heng[0][r1] && heng[1][r1]) rt.ysyx=1;
    	else rt.ysyx=0;
    	if(ls.zsys && rs.zsys && heng[0][r1]) rt.zsys=1;//zsys
    	else if(ls.zsyx && rs.zxys && heng[1][r1]) rt.zsys=1;
    	else rt.zsys=0;
    	if(ls.zsys && rs.zsyx && heng[0][r1]) rt.zsyx=1;//zsyx
    	else if(ls.zsyx && rs.zxyx && heng[1][r1]) rt.zsyx=1;
    	else rt.zsyx=0;
    	if(ls.zxys && rs.zsys && heng[0][r1]) rt.zxys=1;//zxys
    	else if(ls.zxyx && rs.zxys && heng[1][r1]) rt.zxys=1;
    	else rt.zxys=0;
    	if(ls.zxys && rs.zsyx && heng[0][r1]) rt.zxyx=1;//zxyx
    	else if(ls.zxyx && rs.zxyx && heng[1][r1]) rt.zxyx=1;
    	else rt.zxyx=0;
    }
    void update(int p,bool v,int rt,int l,int r)/*µ¥×ÝÁÐÐÞ¸Ä*/
    {
    	if(l==r)
    	  {
    	  	zong[p]=v;
    	  	T[rt].zszx=T[rt].zsyx=T[rt].zxys=T[rt].ysyx=v;
    	  	return;
    	  }
    	int m=(l+r>>1);
    	if(p<=m) update(p,v,rt<<1,l,m);
    	else update(p,v,rt<<1|1,m+1,r);
    	pushup(T[rt],T[rt<<1],T[rt<<1|1],m);
    }
    void update(int p,int rt,int l,int r)/*ÓÉÓÚÅԱߵĺáÐнøÐÐÁËÐ޸Ķø½øÐеĵ¥×ÝÁиüÐÂ*/
    {
    	if(l==r) return;
    	int m=(l+r>>1);
    	if(p<=m) update(p,rt<<1,l,m);
    	else update(p,rt<<1|1,m+1,r);
    	pushup(T[rt],T[rt<<1],T[rt<<1|1],m);
    }
    Node query(int ql,int qr,int rt,int l,int r)
    {
    	if(ql<=l && r<=qr) return T[rt];
    	int m=(l+r>>1);
    	if(ql<=m && m<qr)
    	  {
    	  	Node res;
    	  	pushup(res,query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r),m);
    	  	return res;
    	  }
    	else if(ql<=m) return query(ql,qr,rt<<1,l,m);
    	else return query(ql,qr,rt<<1|1,m+1,r);
    }
    inline bool query(const bool &x1,const int &y1,const bool &x2,const int &y2)
    {
    	Node M=query(y1,y2,1,1,n),L,R;
    	if(y1!=1) L=query(1,y1-1,1,1,n);
    	if(y2!=n) R=query(y2+1,n,1,1,n);
    	if(x1 && x2)
    	  {
    	  	if(M.zxyx) return 1;
    	  	if(y1!=1) if(L.ysyx && M.zsyx && heng[0][y1-1] && heng[1][y1-1]) return 1;
    	  	if(y2!=n) if(R.zszx && M.zxys && heng[0][y2] && heng[1][y2]) return 1;
    	  	if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
    		&& R.zszx && heng[0][y2] && heng[1][y2] && M.zsys)
    		  return 1;
    	  	return 0;
    	  }
    	else if(x1)
    	  {
    	  	if(M.zxys) return 1;
    	  	if(y1!=1) if(L.ysyx && M.zsys && heng[0][y1-1] && heng[1][y1-1]) return 1;
    	  	if(y2!=n) if(R.zszx && M.zxyx && heng[0][y2] && heng[1][y2]) return 1;
    	  	if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
    		&& R.zszx && heng[0][y2] && heng[1][y2] && M.zsyx)
    		  return 1;
    	  	return 0;
    	  }
    	else if(x2)
    	  {
    	  	if(M.zsyx) return 1;
    	  	if(y1!=1) if(L.ysyx && M.zxyx && heng[0][y1-1] && heng[1][y1-1]) return 1;
    	  	if(y2!=n) if(R.zszx && M.zsys && heng[0][y2] && heng[1][y2]) return 1;
    	  	if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
    		&& R.zszx && heng[0][y2] && heng[1][y2] && M.zxys)
    		  return 1;
    	  	return 0;
    	  }
    	else
    	  {
    	  	if(M.zsys) return 1;
    	  	if(y1!=1) if(L.ysyx && M.zxys && heng[0][y1-1] && heng[1][y1-1]) return 1;
    	  	if(y2!=n) if(R.zszx && M.zsyx && heng[0][y2] && heng[1][y2]) return 1;
    	  	if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
    		&& R.zszx && heng[0][y2] && heng[1][y2] && M.zxyx)
    		  return 1;
    	  	return 0;
    	  }
    }
    int main()
    {
    //	freopen("bzoj1018.in","r",stdin);
    	char op[7];
    	int x1,x2,y1,y2;
    	scanf("%d",&n);
    	for(int i=1;i<=(n<<2);++i)
    	  T[i].zsys=T[i].zxyx=1;
    	while(1)
    	  {
    	  	scanf("%s",op);
    	  	if(op[0]=='E') break;
    	  	else if(op[0]=='O')
    	  	  {
    	  	  	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    	  	  	if(y1==y2) update(y1,1,1,1,n);
    	  	  	else
    	  	  	  {
    	  	  	  	if(y1>y2) swap(y1,y2);
    	  	  	  	heng[x1-1][y1]=1;
    	  	  	  	update(y1,1,1,n);
    	  	  	  	update(y2,1,1,n);
    	  	  	  }
    	  	  }
    	  	else if(op[0]=='C')
    	  	  {
    	  	  	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    	  	  	if(y1==y2) update(y1,0,1,1,n);
    	  	  	else
    	  	  	  {
    	  	  	  	if(y1>y2) swap(y1,y2);
    	  	  	  	heng[x1-1][y1]=0;
    	  	  	  	update(y1,1,1,n);
    	  	  	  	update(y2,1,1,n);
    	  	  	  }
    	  	  }
    	  	else
    	  	  {
    	  	  	scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    	  	  	if(y1>y2)
    	  	  	  {
    	  	  	  	swap(x1,x2);
    	  	  	  	swap(y1,y2);
    	  	  	  }
    	  	  	puts(query(x1-1,y1,x2-1,y2) ? "Y" : "N");
    	  	  }
    	  }
    	return 0;
    }
  • 相关阅读:
    在Visual Studio中使用正则表达式匹配换行和批量替换
    Microsoft Visual Studio Ultimate 2013 Update 2 RC 英文版--离线完整安装ISO+简体中文语言包
    TFS 2012 在IE11和Chrome (Windows 8.1) 显示英文的解决方案
    Windows 8 应用商店无法连接到网络的终极完美解决方案
    Visual Studio 2012 Update 4 RC 启动调试失败解决方案
    2013最新版Subversion 1.7.10 for Windows x86 + Apache 2.4.4 x64 安装配置教程+错误解决方案
    PKCS#1
    密钥协商机制
    base64的编码
    认证过程
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4633134.html
Copyright © 2020-2023  润新知