Description

神犇有一个n个节点的图。因为神犇是神犇,所以在T时间内一些边会出现后消失。神犇要求出每一时间段内这个图是否是二分图。这么简单的问题神犇当然会做了,于是他想考考你。

Input

输入数据的第一行是三个整数n,m,T。

第2行到第m+1行,每行4个整数u,v,start,end。第i+1行的四个整数表示第i条边连接u,v两个点,这条边在start时刻出现,在第end时刻消失。

Output

输出包含T行。在第i行中,如果第i时间段内这个图是二分图,那么输出“Yes”,否则输出“No”,不含引号。

Sample Input

  1. 3 3 3
  2. 1 2 0 2
  3. 2 3 0 3
  4. 1 3 1 2

Sample Output

  1. Yes
  2. No
  3. Yes

HINT

样例说明:

0时刻,出现两条边1-2和2-3。

第1时间段内,这个图是二分图,输出Yes。

1时刻,出现一条边1-3。

第2时间段内,这个图不是二分图,输出No。

2时刻,1-2和1-3两条边消失。

第3时间段内,只有一条边2-3,这个图是二分图,输出Yes。

数据范围:

n<=100000,m<=200000,T<=100000,1<=u,v<=n,0<=start<=end<=T。

Solution

首先看怎么静态判能不能二分,一条一条边加进去,如果这条边加上会变成一个环,并且这个环还是奇环,那就不能二分;反之,可以

然后看动态的,动态的麻烦就在删除,因为可能把一条树边删掉之后,会有一条非树边代替它变成一条树边,这个做不了;所以就弄一个LCT维护这个树,维护这个图以删除时间为关键字的最大生成树,这样就不会有上述情况发生了

然后按照套路,离线解决

(PS:从早上开始调,一直调到晚上,开始的时候造数据的程序还写错了,会使标程RE,然后有一次其实改对了,但因为数据造错,一直拍不上,结果就和gt拿了一个正确的程序调了半个小时)

  1. #include<bits/stdc++.h>
  2. #define ui unsigned int
  3. #define ll long long
  4. #define db double
  5. #define ld long double
  6. #define ull unsigned long long
  7. const int MAXN=100000+10,MAXM=200000+10,inf=0x3f3f3f3f;
  8. int n,m,tT,V[MAXN+MAXM],sum,f[MAXN+MAXM];
  9. struct edge{
  10. int u,v;
  11. };
  12. edge side[MAXM];
  13. struct data{
  14. int opt,val,t,id;
  15. inline bool operator < (const data &A) const {
  16. return t<A.t||t==A.t&&opt>A.opt;
  17. };
  18. };
  19. data p[MAXM<<1];
  20. #define lc(x) ch[(x)][0]
  21. #define rc(x) ch[(x)][1]
  22. struct LCT{
  23. int ch[MAXN+MAXM][2],fa[MAXN+MAXM],rev[MAXN+MAXM],Mn[MAXN+MAXM],id[MAXN+MAXM],stack[MAXN+MAXM],cnt,val[MAXN+MAXM],size[MAXN+MAXM];
  24. inline void init()
  25. {
  26. memset(Mn,inf,sizeof(Mn));
  27. memset(val,inf,sizeof(val));
  28. }
  29. inline bool nroot(int x)
  30. {
  31. return lc(fa[x])==x||rc(fa[x])==x;
  32. }
  33. inline void reverse(int x)
  34. {
  35. std::swap(lc(x),rc(x));
  36. rev[x]^=1;
  37. }
  38. inline void pushup(int x)
  39. {
  40. size[x]=size[lc(x)]+size[rc(x)]+1;
  41. Mn[x]=val[x],id[x]=x;
  42. if(Mn[lc(x)]<Mn[x])Mn[x]=Mn[lc(x)],id[x]=id[lc(x)];
  43. if(Mn[rc(x)]<Mn[x])Mn[x]=Mn[rc(x)],id[x]=id[rc(x)];
  44. }
  45. inline void pushdown(int x)
  46. {
  47. if(rev[x])
  48. {
  49. if(lc(x))reverse(lc(x));
  50. if(rc(x))reverse(rc(x));
  51. rev[x]=0;
  52. }
  53. }
  54. inline void rotate(int x)
  55. {
  56. int f=fa[x],p=fa[f],c=(rc(f)==x);
  57. if(nroot(f))ch[p][rc(p)==f]=x;
  58. fa[ch[f][c]=ch[x][c^1]]=f;
  59. fa[ch[x][c^1]=f]=x;
  60. fa[x]=p;
  61. pushup(f);
  62. pushup(x);
  63. }
  64. inline void splay(int x)
  65. {
  66. cnt=0;
  67. stack[++cnt]=x;
  68. for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
  69. while(cnt)pushdown(stack[cnt--]);
  70. for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
  71. if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
  72. pushup(x);
  73. }
  74. inline void access(int x)
  75. {
  76. for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x);
  77. }
  78. inline int findroot(int x)
  79. {
  80. access(x);splay(x);
  81. while(lc(x))pushdown(x),x=lc(x);
  82. splay(x);
  83. return x;
  84. }
  85. inline void makeroot(int x)
  86. {
  87. access(x);splay(x);reverse(x);
  88. }
  89. inline void split(int x,int y)
  90. {
  91. makeroot(x);access(y);splay(y);
  92. }
  93. inline void link(int x,int y)
  94. {
  95. makeroot(x);fa[x]=y;
  96. }
  97. inline void cut(int x,int y)
  98. {
  99. split(x,y);fa[x]=lc(y)=0;pushup(y);
  100. }
  101. };
  102. LCT T;
  103. #undef lc
  104. #undef rc
  105. template<typename T> inline void read(T &x)
  106. {
  107. T data=0,w=1;
  108. char ch=0;
  109. while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
  110. if(ch=='-')w=-1,ch=getchar();
  111. while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
  112. x=data*w;
  113. }
  114. template<typename T> inline void write(T x,char c='\0')
  115. {
  116. if(x<0)putchar('-'),x=-x;
  117. if(x>9)write(x/10);
  118. putchar(x%10+'0');
  119. if(c!='\0')putchar(c);
  120. }
  121. template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
  122. template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
  123. template<typename T> inline T min(T x,T y){return x<y?x:y;}
  124. template<typename T> inline T max(T x,T y){return x>y?x:y;}
  125. inline void add(int now)
  126. {
  127. int u=side[p[now].id].u,v=side[p[now].id].v,sn=p[now].id+n;
  128. if(u==v)
  129. {
  130. f[sn-n]=1;sum++;
  131. return ;
  132. }
  133. if(T.findroot(u)!=T.findroot(v))T.val[sn]=p[now].val,T.link(sn,u),T.link(sn,v),V[sn-n]=1;
  134. else
  135. {
  136. T.split(u,v);
  137. int so=T.id[v],nt=T.size[v]>>1;
  138. if(p[now].val>T.Mn[v])
  139. {
  140. if(!(nt&1))sum++,f[so-n]=1;
  141. T.cut(so,side[so-n].u);
  142. T.cut(so,side[so-n].v);
  143. T.val[sn]=p[now].val;
  144. T.link(sn,u);
  145. T.link(sn,v);
  146. V[so-n]=0;V[sn-n]=1;
  147. }
  148. else if(!(nt&1))sum++,f[sn-n]=1;
  149. }
  150. }
  151. inline void del(int now)
  152. {
  153. int sn=p[now].id+n;
  154. sum-=f[sn-n];
  155. if(V[sn-n])
  156. {
  157. V[sn-n]=f[sn-n]=0;
  158. T.cut(sn,side[sn-n].u);T.cut(sn,side[sn-n].v);
  159. }
  160. else f[sn-n]=0;
  161. }
  162. int main()
  163. {
  164. read(n);read(m);read(tT);
  165. for(register int i=1;i<=m;++i)
  166. {
  167. int u,v,st,ed;
  168. read(u);read(v);read(st);read(ed);
  169. side[i].u=u;side[i].v=v;
  170. p[i].t=st;p[i].val=ed;p[i].id=i;p[i].opt=1;
  171. p[i+m].t=ed;p[i+m].id=i;p[i+m].opt=0;
  172. }
  173. std::sort(p+1,p+m*2+1);
  174. T.init();
  175. for(register int i=1,j=1;i<=tT;++i)
  176. {
  177. for(;p[j].t<i&&j<=m*2;++j)
  178. if(p[j].opt)add(j);
  179. else del(j);
  180. if(sum)puts("No");
  181. else puts("Yes");
  182. }
  183. return 0;
  184. }

【刷题】BZOJ 4025 二分图的更多相关文章

  1. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  2. bzoj 4025 二分图 分治+并查集/LCT

    bzoj 4025 二分图 [题目大意] 有n个点m条边,边会在start时刻出现在end时刻消失,求对于每一段时间,该图是不是一个二分图. 判断二分图的一个简单的方法:是否存在奇环 若存在奇环,就不 ...

  3. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  4. bzoj 4025: 二分图

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. 解题报告: ...

  5. BZOJ 4025 二分图(时间树+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题目大意] 给出一张图,有些边只存在一段时间,问在一个每个时间段, 这张图是否 ...

  6. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  7. 「bzoj 4025: 二分图」

    题目 显然二分图没有奇环 于是考虑使用并查集维护一下看看是否存在奇环 我们可以考虑加权并查集,维护出\(x\)到\(fa_x\)的实际距离 由于我们只需要考虑奇偶性,于是我们处理出到根的路径异或一下就 ...

  8. bzoj 4025 二分图 lct

    题目传送门 题解: 首先关于二分图的性质, 就是没有奇环边. 题目其实就是让你判断每个时段之内有没有奇环. 其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上 ...

  9. BZOJ 4025 二分图 LCT维护最大生成树

    怎么说呢,我也不知道该咋讲,你就手画一下然后 yy 一下就发现这么做是对的. 为什么我明明都想出来了,却还是讲不出来啊~ #include <cstdio> #include <ve ...

随机推荐

  1. weka使用笔记3---classfily API调用

    分类器在数据挖掘中的作用不言而喻,weka中的分类器有很多种类型,但是weka在输出结果中,只输出了一个分类的预测的类型,没有输出分类的得分,有一些不给力.如果想知道得分和其预测的类的话,就得调用we ...

  2. 理解依赖注入(Dependency Injection)

    理解依赖注入 Yii2.0 使用了依赖注入的思想.正是使用这种模式,使得Yii2异常灵活和强大.千万不要以为这是很玄乎的东西,看完下面的两个例子就懂了. class SessionStorage { ...

  3. dp合集 广场铺砖问题&&硬木地板

    dp合集 广场铺砖问题&&硬木地板 很经典了吧... 前排:思想来自yali朱全民dalao的ppt百度文库免费下载 后排:STO朱全民OTZ 广场铺砖问题 有一个 W 行 H 列的广 ...

  4. hive 动态分区插入

    首先需要进行以下设置: set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; se ...

  5. Hibernate5使用注解方式(转)

    用Hibernate5使用映射文件时存在一个问题没有解决,在映射文件中配置了student_sequence,但找不到映射文件自增长的序列的sequence(Oracle)数据库. 输出的是 Hibe ...

  6. 初遇python进程

    计算机硬件组成 主板 固化(寄存器,是直接和cpu进行交互的一个硬件) cpu 中央处理器:计算(数字计算和逻辑计算)和控制(控制所有硬件协调工作) 存储 硬盘,内存 输入设备 键盘,鼠标,话筒 输出 ...

  7. Windows操作系统C盘占用空间过多

    Windows操作系统C盘占用空间过多 大部分的windows电脑用户在长时间使用PC时都会遇到一个问题,就是C盘占用的空间会越来越多,乃至占满整个C盘. 后来在百度了一波,发现各种方法都试过了,也不 ...

  8. linux主机上,UnixBench性能测试工具使用

    1,下载  wget http://soft.laozuo.org/scripts/UnixBench5.1.3.tgz [root@VM_0_15_centos test]# [root@VM_0_ ...

  9. Linux环境下Java应用性能分析定位-CPU使用篇

    1     CPU热点分析定位背景 CPU资源还是很昂贵的,为了深刻感受到这种昂贵,间下图当前CPU的资源售价: 所以对于程序猿们来说,需要让程序合理高效的使用CPU资源.利用有限的CPU资源来解决完 ...

  10. Loadrunner教程--常用操做流程

    1loadrunner压力测试一般使用流程 1.1loadrunner压力测试原理 本质就是在loadrunner上模拟多个用户同时按固定行为访问web站点.其中固定行为在loadrunner中是通过 ...