本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护。

对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边构建起的连通性)。

查询[l,r]时,先计算出[1,l-1],[l,r],[r+1,c]这三个线段的连通性,然后将[l,r]的四个角变成并查集的4个点,先用[l,r]中的6种关系更新,在看是否可以从左上角的点通过左边区间绕道左下角,以及从右上角通过右边区间绕道右下角,该并的并起来后直接看查询的点是否在一个集合即可。

 /**************************************************************
Problem: 1018
User: idy002
Language: C++
Result: Accepted
Time:1472 ms
Memory:2840 kb
****************************************************************/ #include <cstdio>
#include <iostream>
#define maxn 100010
#define AB 1
#define AC 2
#define AD 4
#define BC 8
#define BD 16
#define CD 32
using namespace std; // a b
// c d typedef unsigned Stat; Stat stat[maxn];
int son[maxn][], ntot, root; int c;
bool er[][maxn], ed[maxn]; Stat merge( Stat l, Stat r, int mid ) {
Stat ab = ((l&AB)&&(r&AB)&&er[][mid]) || ((l&AD)&&(r&BC)&&er[][mid]) ? AB : ;
Stat cd = ((l&CD)&&(r&CD)&&er[][mid]) || ((l&BC)&&(r&AD)&&er[][mid]) ? CD : ;
Stat ad = ((l&AB)&&(r&AD)&&er[][mid]) || ((l&AD)&&(r&CD)&&er[][mid]) ? AD : ;
Stat bc = ((l&CD)&&(r&BC)&&er[][mid]) || ((l&BC)&&(r&AB)&&er[][mid]) ? BC : ;
Stat ac = (l&AC) || ((l&AB)&&(l&CD)&&(er[][mid])&&(er[][mid])&&(r&AC)) ? AC : ;
Stat bd = (r&BD) || ((r&AB)&&(r&CD)&&(er[][mid])&&(er[][mid])&&(l&BD)) ? BD : ;
return ab | ac | ad | bc | bd | cd;
}
void update( int nd, int lf, int rg ) {
stat[nd] = merge( stat[son[nd][]], stat[son[nd][]], (lf+rg)>> );
}
int build( int lf, int rg ) {
if( lf>rg ) return ;
int nd = ++ntot;
if( lf==rg ) {
stat[nd] = AB | CD;
return nd;
}
int mid = (lf+rg)>>;
son[nd][] = build( lf, mid );
son[nd][] = build( mid+, rg );
update( nd, lf, rg );
return nd;
}
void modify( int x, int nd, int lf, int rg ) {
if( lf==rg ) {
stat[nd] = AB | CD;
if( ed[lf] )
stat[nd] |= AC | BD | AD | BC;
return;
}
int mid = (lf+rg)>>;
if( x<=mid ) modify(x,son[nd][],lf,mid);
else modify(x,son[nd][],mid+,rg);
update(nd,lf,rg);
}
Stat query( int L, int R, int nd, int lf, int rg ) {
if( L<=lf&&rg<=R ) return stat[nd];
int mid = (lf+rg)>>;
if( R<=mid ) return query( L, R, son[nd][], lf, mid );
if( L>mid ) return query( L, R, son[nd][], mid+, rg );
Stat lstat = query( L, R, son[nd][], lf, mid );
Stat rstat = query( L, R, son[nd][], mid+, rg );
return merge(lstat,rstat,mid);
} int fa[];
void init() {
for( int i=; i<=; i++ ) fa[i]=i;
}
int find( int i ) {
return fa[i]==i ? i : fa[i]=find(fa[i]);
}
void unon( int a, int b ) {
a = find(a);
b = find(b);
fa[a] = b;
}
int main() {
scanf( "%d", &c );
root = build( , c );
while() {
char ch[]; scanf( "%s", ch );
if( ch[]=='E' ) return ;
int ax, ay, bx, by;
scanf( "%d%d%d%d", &ax, &ay, &bx, &by ); if( ch[]=='A' ) {
if( ay>by ) {
swap( ax, bx );
swap( ay, by );
}
Stat sl=, sc=, sr=;
if( ay> ) sl = query(,ay-,root,,c);
sc = query(ay,by,root,,c);
if( by<c ) sr = query(by+,c,root,,c); init();
if( sc&AB ) unon( , );
if( sc&AC ) unon( , );
if( sc&AD ) unon( , );
if( sc&BC ) unon( , );
if( sc&BD ) unon( , );
if( sc&CD ) unon( , );
if( (sl&BD) && er[][ay-] && er[][ay-] ) unon( , );
if( (sr&AC) && er[][by] && er[][by] ) unon( , ); bool ok = false;
if( ax== && bx== ) {
ok = find( ) == find( );
} else if( ax== && bx== ) {
ok = find( ) == find( );
} else if( ax== && bx== ) {
ok = find( ) == find( );
} else if( ax== && bx== ) {
ok = find( ) == find( );
} printf( "%s\n", ok ? "Y" : "N" );
} else {
bool *p;
if( ax==bx ) {
p = &er[ax][min(ay,by)];
} else {
p = &ed[ay];
}
*p = ch[]=='O';
modify( ay, root, , c );
if( ay!=by )
modify( by, root, , c );
}
}
}

bzoj 1018 线段树维护连通性的更多相关文章

  1. BZOJ 1018 线段树维护图的连通性问题

    思路: 我们可以搞一棵线段树 对于一段区间有6种情况需要讨论 左上右下.左上右上.左下右下.左下右上 这四种比较好维护 用左上右下举个例子吧 就是左儿子的左上右下&左区间到右区间下面有路&am ...

  2. BZOJ 1018 线段树维护图连通性

    用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可. Side表示这一块有没有接到右边.Merge一下就可以了.码农题,WA了一 ...

  3. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  4. BZOJ.1018.[SHOI2008]堵塞的交通(线段树维护连通性)

    题目链接 只有两行,可能的路径数不多,考虑用线段树维护各种路径的连通性. 每个节点记录luru(left_up->right_up),lurd,ldru,ldrd,luld,rurd,表示这个区 ...

  5. [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 3795  Solved: 1253 [Sub ...

  6. BZOJ 2124 线段树维护hash值

    思路: http://blog.csdn.net/wzq_QwQ/article/details/47152909 (代码也是抄的他的) 自己写得垃圾线段树怎么都过不了 隔了两个月 再写 再挂 又隔了 ...

  7. bzoj 4127 线段树维护绝对值之和

    因为d>=0,所以一个位置的数只会单调不降并且只会有一次穿过0. 用这个性质,我们我可在线段树中记录正数负数的个数和和,以及最大的负数以及答案. 修改操作:如果当前最大负数+d<=0,那么 ...

  8. [BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

    题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经 ...

  9. BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)

    BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...

随机推荐

  1. NYOJ 267 郁闷的C小加(二) (字符串处理)

    题目链接 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考"郁闷的C小加(一)"),C小加很高兴.但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值 ...

  2. Go语言 5 函数

    文章由作者马志国在博客园的原创,若转载请于明显处标记出处:http://www.cnblogs.com/mazg/ 今天,我们来学习Go语言编程的第五章,函数.首先简单说一下函数的概念和作用.函数是一 ...

  3. 蓝色的PC端后台管理界面设计模板——后台

    链接:http://pan.baidu.com/s/1o82hXX4 密码:x6le

  4. React Native DEMO for Android

    Demo1: 主要知识:navigator,fecth 地址:https://github.com/hongguangKim/ReactNativeDEMO1 Demo2: 主要知识:navigato ...

  5. 可能是是最全的Springboot基础视频分享,告别无视频可学

    一头扎进SpringBoot视频教程 SpringBoot入门 2017年-张志君老师-SpringBoot(新增) 欢迎关注我的微信公众号:"Java面试通关手册" 回复关键字& ...

  6. 自动ftp 上传

    #!/bin/sh ftp -n<<END_FTP open 192.168.1.4 user codfei duibuqi //用户名codfei 密码duibuqi binary pr ...

  7. Getting Started with Django Rest Framework and AngularJS

    转载自:http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html A ReST ...

  8. PyQt:eg4

    import sys from PyQt4 import QtCore from PyQt4 import QtGui class Form(QtGui.QDialog): def __init__( ...

  9. NFS生产场景优化

    1.硬件上多块网卡bond,增加吞吐量,至少千兆.sas/ssd磁盘组raid5或raid10 2.服务端配置:/data 172.16.1.0/24(rw,sync,all_squash,anonu ...

  10. leetcode 之Permutation(七)

    首先是next permutation的算法的描述和分析如下: 这题一是要知道思路,编程中注意STL的用法 void nextPermutaion(vector<int> &num ...