传送门

线段树分治好题。


这道题实际上有很多不同的做法:

cdq分治。

lct。



而我学习了dzyo的线段树分治+并查集写法。

所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的区间分别维护信息。

最后按线段树从上到下再从左到右的遍历方式一起统计答案。

这道题可以按时间建树,每次相当于在一段区间里增加边。

最后统计二分图就行了,这个问题可以用并查集解决。

然而我们回溯上去的时候是需要撤销操作的,因此需要用并查集按秩合并。

代码:

  1. #include<bits/stdc++.h>
  2. #define N 100005
  3. #define lc (p<<1)
  4. #define rc (p<<1|1)
  5. using namespace std;
  6. inline int read(){
  7. int ans=0;
  8. char ch=getchar();
  9. while(!isdigit(ch))ch=getchar();
  10. while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
  11. return ans;
  12. }
  13. int n,m,T,ans[N],fa[N],h[N],col[N];
  14. vector<pair<int,int> >e[N<<2];
  15. struct node{
  16. pair<int,int>x;
  17. bool f;
  18. node(pair<int,int>x_,bool f_):x(x_),f(f_){}
  19. };
  20. vector<node>g[N<<2];
  21. inline void update(int p,int l,int r,int ql,int qr,int u,int v){
  22. if(ql>r||qr<l)return;
  23. if(ql<=l&&r<=qr){e[p].push_back(make_pair(u,v));return;}
  24. int mid=l+r>>1;
  25. if(qr<=mid)update(lc,l,mid,ql,qr,u,v);
  26. else if(ql>mid)update(rc,mid+1,r,ql,qr,u,v);
  27. else update(lc,l,mid,ql,qr,u,v),update(rc,mid+1,r,ql,qr,u,v);
  28. }
  29. inline int findcol(int&p){
  30. int ret=0;
  31. while(p!=fa[p])ret^=col[p],p=fa[p];
  32. return ret;
  33. }
  34. inline void query(int p,int l,int r){
  35. bool f=false;
  36. for(int i=0;i<e[p].size();++i){
  37. int u=e[p][i].first,v=e[p][i].second,a=findcol(u),b=findcol(v);
  38. if(u==v){
  39. if(a==b){
  40. f=true;
  41. for(int i=l;i<=r;++i)ans[i]=0;
  42. break;
  43. }
  44. continue;
  45. }
  46. if(h[u]<h[v])swap(u,v);
  47. fa[v]=u,col[v]=a^b^1;
  48. bool tmp=0;
  49. if(h[u]==h[v])h[u]+=(tmp=1);
  50. g[p].push_back(node(make_pair(u,v),tmp));
  51. }
  52. int mid=l+r>>1;
  53. if(l!=r&&!f)query(lc,l,mid),query(rc,mid+1,r);
  54. for(int i=g[p].size()-1;~i;--i){
  55. int u=g[p][i].x.first,v=g[p][i].x.second;
  56. fa[v]=v,col[v]=0,h[u]-=g[p][i].f;
  57. }
  58. }
  59. int main(){
  60. n=read(),m=read(),T=read();
  61. for(int i=1;i<=n;++i)fa[i]=i,ans[i]=h[i]=1;
  62. for(int i=1;i<=m;++i){
  63. int u=read(),v=read(),l=read()+1,r=read();
  64. if(l>r)continue;
  65. update(1,1,T,l,r,u,v);
  66. }
  67. query(1,1,T);
  68. for(int i=1;i<=T;++i)if(ans[i])puts("Yes");else puts("No");
  69. return 0;
  70. }

2018.09.30 bzoj4025: 二分图(线段树分治+并查集)的更多相关文章

  1. bzoj4025二分图(线段树分治 并查集)

    /* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...

  2. [BZOJ4025]二分图(线段树分治,并查集)

    4025: 二分图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2191  Solved: 800[Submit][Status][Discuss] ...

  3. BZOJ4025 二分图(线段树分治+并查集)

    之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...

  4. BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)

    Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...

  5. BZOJ3237 AHOI2013连通图(线段树分治+并查集)

    把查询看做是在一条时间轴上.那么每条边都有几段存在时间.于是线段树分治就好了. 然而在bzoj上t掉了,不知道是常数大了还是写挂了. 以及brk不知道是啥做数组名过不了编译. #include< ...

  6. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  7. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)

    传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...

  8. BZOJ4025 二分图 线段树分治、带权并查集

    传送门 如果边不会消失,那么显然可以带权并查集做(然后发现自己不会写带权并查集) 但是每条边有消失时间.这样每一条边产生贡献的时间对应一段区间,故对时间轴建立线段树,将每一条边扔到线段树对应的点上. ...

  9. Codeforces 1140F Extending Set of Points (线段树分治+并查集)

    这题有以下几个步骤 1.离线处理出每个点的作用范围 2.根据线段树得出作用范围 3.根据分治把每个范围内的点记录和处理 #include<bits/stdc++.h> using name ...

随机推荐

  1. Redis hash数据结构

    1, 新增一个 hash 或者 新增数据 => hset key field value 2, 获取某个字段值 => hset key field 3, 获取所有字段值 => hge ...

  2. cnapckSurround c++builder Region 代码折叠快捷键

    C++Builder代码折叠 cnapckSurround c++builder Region 代码折叠快捷键,可以导入导出,IDE code edit,cnpack menu surround wi ...

  3. java ee7 -- Java Bean验证

    针对对象.对象成员.方法.构造函数的数据验证. 1. 一个验证的小例子 (1) 添加引用jar <dependency> <groupId>org.hibernate.vali ...

  4. iOS toll-free bridge

    https://developer.apple.com/library/ios/documentation/CoreFoundation/Conceptual/CFDesignConcepts/Art ...

  5. jquery 判断checkbox是否被选中问题

    1.jquery库2以上 $("#checkbox_check").click(function(){ alert($(this).prop("checked" ...

  6. chnagyong sql

    select gid,count(distinct mid) from members group by gid mysql> SELECT IFNULL(NULL,); mysql> 1 ...

  7. SSH框架整合过程总结

    ---------------------siwuxie095                                 SSH 框架整合过程总结         (一)导入相关 jar 包(共 ...

  8. tcp连接需要注意的问题

    当有子进程时,子进程终止时会返回SIGCHLD信号,默认忽略,此时会有僵尸进程. 处理方法: 捕获信号,并waitpid. 当慢系统调用被中断时(如信号中断),有些系统不会自动重启调用,此时系统调用可 ...

  9. UVa 10763 Foreign Exchange(map)

    Your non-profitorganization (iCORE - international Confederationof Revolver Enthusiasts) coordinates ...

  10. 【校招面试 之 C/C++】第18题 C++ 中的隐式转换以及explicit关键字

    1.什么是隐式转换: 众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的. 所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为.很多时候用户可能都不知道进行了 ...