Codeforces 576E Painting Edges [分治,并查集]
建议阅读这篇博客作为预备。无耻地打广告
思路
与bzoj4025很相似,思路也差不多,可以看上面那篇博客。
仍然是用二分图的充要条件:没有奇环。
然而这题难在每条边的存在时间不固定,无法一开始知道。
可以每次在加入这条边的时间点判断能否成功修改,确定接下来一段时间它的颜色是什么。
具体见代码。
代码
#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define sz 505050
typedef long long ll;
template<typename T>
inline void read(T& t)
{
t=0;char f=0,ch=getchar();
double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.')
{
ch=getchar();
while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();
}
t=(f?-t:t);
}
template<typename T,typename... Args>
inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n,m,K,Q;
struct hh{int u,v,col;}edge[sz];
int id[sz],las[sz],L[sz],R[sz],pre[sz],col[sz];
struct hhhh{int x,y,col;bool s;};
struct hhh
{
int fa[sz],f[sz],dep[sz];
int getfa(int x){return x==fa[x]?x:getfa(fa[x]);}
int getdis(int x){return x==fa[x]?0:f[x]^getdis(fa[x]);}
void cancel(hhhh a){f[fa[a.x]=a.x]=0;dep[a.y]-=a.s;}
bool connected(int x,int y){return getfa(x)==getfa(y);}
hhhh merge(int x,int y,int col)
{
int fx=getfa(x),fy=getfa(y);
if (dep[fx]>dep[fy]) swap(fx,fy),swap(x,y);
int w=getdis(x)^getdis(y)^1;
hhhh ret=(hhhh){fx,fy,col,0};
f[fx]=w;fa[fx]=fy;
if (dep[fx]==dep[fy]) ++dep[fy],ret.s=1;
return ret;
}
}G[55];
void cancel(stack<hhhh>S){while (!S.empty()) G[S.top().col].cancel(S.top()),S.pop();}
vector<int>v[sz<<2];
#define ls k<<1
#define rs k<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
void insert(int k,int l,int r,int x,int y,int e)
{
if (x<=l&&r<=y) return (void)(v[k].push_back(e));
int mid=(l+r)>>1;
if (x<=mid) insert(lson,x,y,e);
if (y>mid) insert(rson,x,y,e);
}
void solve(int k,int l,int r)
{
stack<hhhh>S;
rep(i,0,(int)v[k].size()-1)
{
hh e=edge[v[k][i]];
if (!e.col) continue;
int x=e.u,y=e.v,col=e.col;
if (G[col].connected(x,y)) continue;
S.push(G[col].merge(x,y,col));
}
if (l==r)
{
hh e=edge[id[l]];
int w=G[col[l]].getdis(e.u)^G[col[l]].getdis(e.v)^1;
bool t=G[col[l]].connected(e.u,e.v);
cancel(S);
if (!t||!w) return (void)(puts("YES"),edge[id[l]].col=col[l]);
return (void)puts("NO");
}
int mid=(l+r)>>1;
solve(lson);solve(rson);
cancel(S);
}
int main()
{
file();
int x,y;
read(n,m,K,Q);
rep(i,1,K) rep(j,1,n) G[i].fa[j]=j;
rep(i,1,m) read(x,y),edge[i]=(hh){x,y,0};
rep(i,1,Q)
{
read(x,y);
id[i]=x;col[i]=y;
if (las[x]) R[las[x]]=i-1;
pre[i]=las[x];las[x]=i;
L[i]=i+1,R[i]=Q;
}
rep(i,1,Q) if (L[i]<=R[i]) insert(1,1,Q,L[i],R[i],id[i]);
solve(1,1,Q);
return 0;
}
Codeforces 576E Painting Edges [分治,并查集]的更多相关文章
- Codeforces 1140F 线段树 分治 并查集
题意及思路:https://blog.csdn.net/u013534123/article/details/89010251 之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接 ...
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
- Codeforces 699D Fix a Tree 并查集
原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...
- Codeforces 731C:Socks(并查集)
http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...
- codeforces 400D Dima and Bacteria 并查集+floyd
题目链接:http://codeforces.com/problemset/problem/400/D 题目大意: 给定n个集合,m步操作,k个种类的细菌, 第二行给出k个数表示连续的xi个数属于i集 ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
随机推荐
- 【51nod 1785】数据流中的算法
Description 51nod近日上线了用户满意度检测工具,使用高级人工智能算法,通过用户访问时间.鼠标轨迹等特征计算用户对于网站的满意程度. 现有的统计工具只能统计某一个窗口中,用户的满意程 ...
- Docker 容器文件导出 - 六
Docker 容器 导入导出 导入:import 导出:export 打tar包导出容器 nginx1 的文件系统: # docker export nginx1 > nginx1.tar.gz ...
- 用Kersa搭建神经网络【MNIST手写数据集】
MNIST手写数据集的识别算得上是深度学习的”hello world“了,所以想要入门必须得掌握.新手入门可以考虑使用Keras框架达到快速实现的目的. 完整代码如下: # 1. 导入库和模块 fro ...
- linux atoi
atoi 只能针对字符串为数字, 对字符串为十六进制.八进制的不能进行转化
- java解压缩zip
依赖的包: <!-- https://mvnrepository.com/artifact/org.apache.ant/ant --> <dependency> <gr ...
- C++ std::pair的用法
1 pair的应用 pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存.另一个应用是,当一个函数需要返回2个数据的时候, ...
- 【VMware vSphere】vCenter添加主机失败:无法访问指定主机
背景 前一段时间,给一台服务器安装ESXi系统,安装成功之后,通过vCenter在上面安装了一台VDP系统.结果前几天发现服务器掉线,重新连接时出现问题.问题描述如下: 其中错误堆栈具体内容为:在 v ...
- Go语言中的struct tag
有时在Go的结构体定义时会看到这样的形式: type User struct { UserId int `json:"user_id" bson:"b_user_id&q ...
- 无法修改linux/ubuntu密码(Authentication token manipulation error )问题解决过程【转】
转自:https://blog.csdn.net/caizi001/article/details/38659189 Vmware虚拟机里的ubunut系统长期不用,密码忘记了,无奈只能通过slax ...
- 题解-USACO18DEC Sort It Out
Problem 洛谷5156 题意概要:给定一个长为\(n\)的排列,可以选择一个集合\(S\)使这个集合内部元素排到自己在整个序列中应该在的位置(即对于集合\(S\)内的每一个元素\(i\),使其排 ...