博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj4025 二分图
阅读量:7096 次
发布时间:2019-06-28

本文共 2565 字,大约阅读时间需要 8 分钟。

其实直接lct完事了。。。

但是太暴力不好看。。。

 

每个边存在于一个时间区间

对于每个时间区间都有询问

线段树分治!

dfs最后扫一遍

并查集按秩合并!

奇环?

并查集树上每个边维护这个点到并查集父亲节点在真实树中的距离奇偶性

发现,这个奇偶性可以直接异或的(可以认为一条边走过两次就是没有走过)

所以直接更新即可。

用栈维护事情,连接两个点或者出现了奇环(这个只第一次放进去即可)

代码:

O(nlog^2n)但是比lct常数小

#include
#define reg register int#define il inline#define mid ((l+r)>>1)#define numb (ch^'0')using namespace std;typedef long long ll;il void rd(int &x){ char ch;x=0;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x);}namespace Miracle{const int N=100000+5;const int M=200000+5;int n,m,T;struct node{ int x,y;}b[M];vector
mem[4*N];int fa[N];int sz[N];int dis[N];int fin(int x){ return fa[x]==x?x:fin(fa[x]);}int dist(int x){ return fa[x]==x?dis[x]:dis[x]^dist(fa[x]);}void upda(int x,int l,int r,int L,int R,int id){ if(L<=l&&r<=R){ mem[x].push_back(id); return; } if(L<=mid) upda(x<<1,l,mid,L,R,id); if(mid
sz[k2]) swap(k1,k2); fa[k1]=k2; sz[k2]+=sz[k1]; dis[k1]=dist(b[mem[x][i]].x)^dist(b[mem[x][i]].y)^1; sta[++top].id=mem[x][i]; sta[top].chan=k1,sta[top].to=k2; }else if(fl){ if((dist(b[mem[x][i]].x)^dist(b[mem[x][i]].y))==0){ fl=false; ++top; sta[top].id=-1; sta[top].chan=0; sta[top].to=0; } } } if(l==r){ puts(fl?"Yes":"No"); }else{ dfs(x<<1,l,mid); dfs(x<<1|1,mid+1,r); } while(top!=st){ if(sta[top].id==-1){ fl=true; }else{ sz[sta[top].to]-=sz[sta[top].chan]; fa[sta[top].chan]=sta[top].chan; dis[sta[top].chan]=0; } --top; }}int main(){ rd(n);rd(m);rd(T); for(reg i=1;i<=n;++i) fa[i]=i,dis[i]=0,sz[i]=1; int l,r; for(reg i=1;i<=m;++i){ rd(b[i].x);rd(b[i].y); rd(l);rd(r); ++l;//warning !!! if(l<=r)upda(1,1,T,l,r,i); } fl=true; dfs(1,1,T); return 0;}}signed main(){ Miracle::main(); return 0;}/* Author: *Miracle* Date: 2019/2/10 20:59:09*/

总结:

1.时间区间存在,可以想到线段树分治

2.并查集的维护距离的奇偶性的xor有点trick!

 

 

(这个题也可以对时间分治:[L,R]对于横跨[L,R]的边,拆成两个,分治下去。

但是如果到L=R的时候才停止的话,每个边拆成T个,就TLE了

发现,如果对于[l,r],如果一个边全程都出现在[l,r]中的话,那么就先加进去,就不拆开往下递归了

显然也是正确的

这样,每个边拆成log(T)份(类似线段树)

需要删除,并查集按秩合并(dis也是要维护的)

复杂度:O(mlog(T)log(N))

这个方法就是线段树分治。。。。

只不过线段是边分治边下放而已。

转载于:https://www.cnblogs.com/Miracevin/p/10360358.html

你可能感兴趣的文章
增加网站点击(引流)的不外传seo技巧
查看>>
转载:Expression 表达式树学习整理
查看>>
jvm系列(五):Java GC 分析
查看>>
在Docker Toolbox和Boot2Docker中使用Volume Plugins
查看>>
【独家】一文读懂文字识别(OCR)
查看>>
安卓程序员要拿到5000和1w的薪资,分别需要掌握哪些技术?
查看>>
浅谈机器视觉技术未来发展趋势
查看>>
[译] 前端调试技巧与诀窍
查看>>
从零开始写linux字符设备驱动程序(一)(基于友善之臂tiny4412开发板)
查看>>
ASP.NET MVC Model元数据及其定制:一个重要的接口IMetadataAware
查看>>
java基础知识——网络编程、IO流
查看>>
“层云”架构有望打破云计算瓶颈
查看>>
Gartner公布2017年顶级安全技术
查看>>
怎么学python?
查看>>
GitLab-CI持续集成(CI)的介绍与运行机制
查看>>
CNCC 2017大会第一天,邱成桐,梅宏,沈向洋,李飞飞,汤道生,马维英都讲了什么?...
查看>>
医疗+AI面临哪些机遇和挑战?阿里健康、飞利浦、辉瑞、阿斯利康的高管们如是说...
查看>>
信维科技:做通信测试领域的“华为”
查看>>
Apache 软件基金会 18 周年,晒最新“成绩单”
查看>>
《沟通的技术——让交流、会议与演讲更有效》一2.1 释放你的天性
查看>>