【CF813F】Bipartite Checking(线段树分治+可删除并查集)

文章目录

  • title
  • solution
  • code

title

You are given an undirected graph consisting of n vertices. Initially there are no edges in the graph. Also you are given q queries, each query either adds one undirected edge to the graph or removes it. After each query you have to check if the resulting graph is bipartite (that is, you can paint all vertices of the graph into two colors so that there is no edge connecting two vertices of the same color).

题意翻译
给你一个由n个顶点组成的无向图,最初在图中没有边。同时给你q次查询,每次查询时会向图中添加一个无向边或者删除一个无向边。 在每次查询之后,您必须检查结果图是否为二分图(在保证没有连接相同颜色的两个顶点的边的条件下,您可以将图的所有顶点绘制为两种颜色)

Input
The first line contains two integers n and q (2 ≤ n, q ≤ 100000).

Then q lines follow. ith line contains two numbers x i and y i (1 ≤ x i < y i ≤ n). These numbers describe ith query: if there is an edge between vertices x i and y i, then remove it, otherwise add it.

Output
Print q lines. ith line must contain YES if the graph is bipartite after ith query, and NO otherwise.

Example
Input
3 5
2 3
1 3
1 2
1 2
1 2
Output
YES
YES
NO
YES
NO

solution

线段树分治的概念打开百度一找一大堆

以时间建线段树,把区间操作懒标记打在点上,查询时开始下放修改,回溯的时候把影响改回去

相同的边如果是第奇数次出现就是加边,第偶数次出现就是删边
因此我们可以排序,把相同的边排在一起,并且按时间从小到大,假设iii为奇数
这条边存在的时间就是[t[i],t[i+1])[t[i],t[i+1])[t[i],t[i+1]),如果iii是最后一条边,就意味着这条边从该时刻开始会一直存在到最后
把这些边以存在时间段分别插入线段树,就跟普通线段树一样打懒标记
当然对于某个时刻肯定不止有一条边,所以就把线段树的节点开成vectorvectorvector一次性塞进去

完了后就开始查询,可以知道每一个叶子结点都是一次答案查询,一路上把懒标记释放出去
但是为了方便回溯时清除对另外一个查询无用的影响
我们这里就要使用可删除并查集,就是记录在点时放进去的所有操作,然后回溯到该点的时候将所有操作逆着来一遍,回推到初始状态

具体的看代码就懂了

code

#include <cstdio>
#include <vector>
#include<iostream>
#include <algorithm>
using namespace std;
#define MAXN 100005
struct node { int u, v, t; } edge[MAXN];
vector < int > tree[MAXN << 2];
int n, Q, Top;
int f[MAXN], st[MAXN], dep[MAXN], color[MAXN];int calc( int x ) { return ( f[x] == x ) ? 0 : calc( f[x] ) ^ color[x]; }void MakeSet() { for( int i = 1;i <= n;i ++ ) f[i] = i; }int findSet( int x ) { return ( x == f[x] ) ? x : findSet( f[x] ); }void Merge( int u, int v, int flag ) {u = findSet( u ), v = findSet( v );if( dep[u] < dep[v] ) swap( u, v );else if( dep[u] == dep[v] ) dep[u] ++, st[++ Top] = -u;f[v] = u, color[v] = flag, st[++ Top] = v;
}void regret( int last ) {while( Top > last ) {if( st[Top] < 0 ) dep[-st[Top]] --;else f[st[Top]] = st[Top], color[st[Top]] = 0;Top --;}
}bool cmp( node x, node y ) {if( x.u == y.u ) return ( x.v == y.v ) ? x.t < y.t : x.v < y.v;else return x.u < y.u;
}void modify( int t, int l, int r, int L, int R, int id ) {if( L <= l && r <= R ) { tree[t].push_back( id ); return; }int mid = ( l + r ) >> 1;if( L <= mid ) modify( t << 1, l, mid, L, R, id );if( mid < R ) modify( t << 1 | 1, mid + 1, r, L, R, id );
}void dfs( int t, int l, int r ) {int now = Top;for( int i = 0;i < tree[t].size();i ++ ) {int u = edge[tree[t][i]].u, v = edge[tree[t][i]].v;int flag = calc( u ) ^ calc( v ) ^ 1;if( findSet( u ) == findSet( v ) ) {if( flag ) {for( int j = l;j <= r;j ++ )printf( "NO\n" );regret( now );return;}}else Merge( u, v, flag );}if( l == r ) {regret( now );printf( "YES\n" );return;}int mid = ( l + r ) >> 1;dfs( t << 1, l, mid );dfs( t << 1 | 1, mid + 1, r );regret( now );
}int main() {scanf( "%d %d", &n, &Q );MakeSet();for( int i = 1, u, v;i <= Q;i ++ ) {scanf( "%d %d", &edge[i].u, &edge[i].v );edge[i].t = i;}sort( edge + 1, edge + Q + 1, cmp );for( int i = 1;i <= Q;i ++ )if( edge[i].u == edge[i + 1].u && edge[i].v == edge[i + 1].v )modify( 1, 1, Q, edge[i].t, edge[i + 1].t - 1, i ), i ++;elsemodify( 1, 1, Q, edge[i].t, Q, i );dfs( 1, 1, Q );return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317933.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在.Net Core WebAPI下给Swagger增加导出离线文档功能

一丶前言最近刚接触到Swagger&#xff0c;在github上下载了它的源码和demo学习了一遍&#xff0c;发现这个组件非常好用&#xff0c;不过不足的是它没有导出离线文档的功能&#xff0c;于是乎我就想给它加一个导出功能Swagger Github开源地址二丶思路其实说白了api文档就是一个…

P7920-[Kubic]Permutation

正题 题目链接:https://www.luogu.com.cn/problem/P7920 题目大意 一个排列ppp生成的森林的形式如下&#xff0c;对于每个iii找到最大的j∈[1,i)j\in [1,i)j∈[1,i)满足 pi>pjp_i>p_jpi​>pj​&#xff0c;然后连一条i,ji,ji,j之间的边。 给出一张树GGG&#xff0c;…

YBTOJ洛谷P4331:数字序列(左偏树)

文章目录题目描述数据范围解析代码题目描述 数据范围 n<1e6n<1e6n<1e6 解析 先考虑简单情况 如果原数列是单调递增的&#xff0c;显然应该使biaib_ia_ibi​ai​ 如果单调递减&#xff0c;应该取中位数 那么原数列如果分成单调递减的几段&#xff0c;那么每一段都取中…

P8441 旭日东升(二维数点经典套路)

P8441 旭日东升 维护一个不可重集合的序列 \(a\)&#xff0c;长度为 \(n\)。支持以下两种操作&#xff1a; l r x 对于每个 \(l\le i\le r\)&#xff0c;将 \(x\) 并入 \(a_i\)。l r 设 \(S\) 把每个 \(l\le i\le r\) 的 \(a_i\) 并在一起的集合&#xff0c;输出 \(S\) 中所有元…

深搜、广搜、搜索剪枝

搜索与回溯讲解 文章目录深搜方向向量&#xff1a;DFS代码&#xff1a;题目讲解&#xff1a;八皇后问题字符序列自然数的拆分广搜BFS代码&#xff1a;题目讲解&#xff1a;瓷砖关系网络bfs与dfs的用途与区别搜索剪枝可行性剪枝最优性剪枝记忆化搜索搜索顺序剪枝题目&#xff1a…

使用logdashboard查看可视化日志

logdashboard日志面板是我在Github写的一个开源项目&#xff0c;旨在让查看日志变的方便快捷。在线预览现在功能有日志检索、趋势图、异常堆栈快速查看、日志详情等logdashboard支持自定义日志模型可以记录更多自定义的属性。logdashboard支持的日志来源有以下两种&#xff0c;…

CF1603C-Extreme Extension【整除分块,dp】

正题 题目链接:http://codeforces.com/contest/1603/problem/C 题目大意 定义一个序列aaa的f(a)f(a)f(a)为你每次可以将序列中的一个数zzz分裂成xyzxyzxyz&#xff0c;然后再把x,yx,yx,y放回原来的位置&#xff0c;然后f(a)f(a)f(a)表示把aaa变成不降序列的最少操作次数 给出…

数论分块专题复习(余数求和+模积和+Ice Rain+The Fool)

文章目录前提知识复习T1&#xff1a;余数求和titlesolutioncodeT2&#xff1a;Ice RaintitlesolutioncodeT3&#xff1a;The FooltitlesolutioncodeT4&#xff1a;模积和titlesolutioncode前提知识复习 整除分块是用于快速处理形似下列式子的方法&#xff0c;是解决莫比乌斯反…

SP1557 GSS2 - Can you answer these queries II(离线 线段树)

SP1557 GSS2 - Can you answer these queries II \(\bigstar\texttt{Hint}\)&#xff1a;遇到去重的问题&#xff0c;我们通常考虑离线询问后处理。 可以枚举右端点&#xff0c;将询问存储在右端点&#xff0c;考虑用数据结构记录左端点的信息。 那么我们如果用线段树维护左端点…

模板:K-D tree

文章目录前言思想能解决的问题操作建树询问修改完整代码所谓KDtree&#xff0c;就是有K个D的树 &#xff08;逃&#xff09; 前言 KDtree是一种解决多维问题的暴力数据结构 K维状态下的最差复杂度是nk−1/kn^{k-1/k}nk−1/k 在最常见的2Dtree中就是根号n 但是玄学的它常常能到…

AT3877-[ARC089C]GraphXY【构造】

正题 题目链接:https://www.luogu.com.cn/problem/AT3877 题目大意 给出一个大小为ABA\times BAB的矩阵ddd 要求构造一个点数不超过300300300的有向图满足 图中没有重边和自环图中的边权为[0,100][0,100][0,100]的整数或者未知数X/YX/YX/Y对于所有X∈[1,A],Y∈[1,B]X\in[1,A…

领域驱动设计,让程序员心中有码(六)

领域驱动设计-聚合&#xff0c;一种极简的思维模式引言作为IT技术产业飞速发展的产物&#xff0c;软件工程学已经成为当今时代非常重要的一个学科。作为一名资深的软件开发从业者&#xff0c;我们需要学习的东西实际上已经远远超出了原本在大学教育阶段所接受的知识深度和广度&…

CF856D Masha and Cactus(树上 DP+抵消贡献技巧)

CF856D Masha and Cactus 我们先捞出一个根节点&#xff0c;那么一次旋变就是对路径上点的覆盖。 设 \(dp_{i,0}\) 表示 \(i\) 没有选择时子树内最大收益&#xff0c;\(dp_{i,1}\) 表示 \(i\) 选择时子树内最大收益&#xff0c;那么将每条边存在 \(lca\) 上。 之后贡献怎么算&a…

hdu 5094 Maze

题意&#xff1a; n*m大的迷宫 &#xff0c;有p种钥匙。钥匙最多有10种。 然后一个k&#xff0c;然后k行表示 (x1,y1),(x2,y2)直接有门或者墙。 如果g0 &#xff0c;就是有墙&#xff0c; 如果g>0 表示有门&#xff0c;且门需要第g把钥匙才能开。 然后下来一个s&#xff…

数论分块练习([CF830 C]Bamboo Partition + [hdu 6395]Sequence )

文章目录T1&#xff1a;SequencetitlesolutionT2&#xff1a;Bamboo PartitiontitlesolutioncodeT1&#xff1a;Sequence title 传送 solution 一眼就是很裸的矩阵加速 ⌊pl⌋\lfloor\frac{p}{l}\rfloor⌊lp​⌋分块矩阵加速就可以了 [BA1][DC⌊pl⌋010001]\begin{bmatrix}…

YBTOJ:染颜色(KDtree)

文章目录题目描述数据范围解析代码题目描述 数据范围 n≤105,T≤5n\le10^5,T\le5n≤105,T≤5 解析 关键是对问题的转化 考虑一次修改&#xff0c;一个点需要满足哪些条件才可以满足 1.与x的距离不超过lll 2.在x的子树内 这两个条件可以转化为对深度的限制和对dfs序的限制 这样…

Kubernetes初探[1]:部署你的第一个ASP.NET Core应用到k8s集群

Kubernetes简介Kubernetes是Google基于Borg开源的容器编排调度引擎&#xff0c;作为CNCF&#xff08;Cloud Native Computing Foundation&#xff09;最重要的组件之一&#xff0c;它的目标不仅仅是一个编排系统&#xff0c;而是提供一个规范&#xff0c;可以让你来描述集群的架…

P5933 [清华集训2012]串珠子(连通性 状压 计数)

P5933 [清华集训2012]串珠子 \(\color{yellow}{\bigstar\texttt{Trick}}\)&#xff1a;遇到连通性题可以暂时忽略是否联通。 设 \(g_s\) 表示集合为 \(s\) 的点的子图有多少个&#xff0c;可以不连通&#xff1b;\(f_s\) 表示答案。 那么 \(g_s\) 可以直接计算 \(g_s\prod_{(i&…

AT2365-[AGC012E]Camel and Oases【状压dp】

正题 题目链接:https://www.luogu.com.cn/problem/AT2365 题目大意 一个数轴上有nnn个点&#xff0c;开始你有个水壶容量为VVV&#xff0c;你每次有两个操作 走到一个距离与你不超过VVV的点让V⌊V2⌋V\lfloor\frac V2\rfloorV⌊2V​⌋&#xff0c;然后跳到任意一个点。 对于…

01分数规划

参考文章 01分数规划 什么是01分数规划&#xff1a; 给定n个a[i]和b[i]&#xff0c;a[i]和b[i]绑定在一起要选同时选&#xff0c;求sum(a[i]) 除以 sum(b[i]) 的最大值&#xff0c;sum为求和函数 对于这种问题我们可以多定义一个数组x[1…n]&#xff0c;x为bool型只取0或者1,…