zoukankan      html  css  js  c++  java
  • P5787 二分图 /【模板】线段树分治

    ( ext{Solution})

    线段树分治的模板
    对时间分治,线段树下标表示时间
    在线段树上处理每条覆盖当前区间的边,对当前的时间区间求答案
    小区间的信息可以由大区间一路下来得到,那么答案就是叶子节点的答案

    对于二分图的加边动态判定,可以用并查集维护
    具体来说就是用带权并查集,维护每个点与其父亲点集的异同
    因为线段树区间返回时需要撤销并查集操作,那么就打个可撤销并查集按秩合并即可

    ( ext{Code})

    #include <cstdio>
    #include <iostream>
    #define re register
    #define ls (p << 1)
    #define rs (ls | 1)
    using namespace std;
    
    const int N = 2e5 + 5;
    int n, m, k, tot, top;
    struct node{
    	int x, y;
    	inline node(int u = 0, int v = 0){x = u, y = v;}
    }e[N];
    int Q[N << 2];
    struct edge{
    	int nxt, to;
    	inline edge(int x = 0, int y = 0){nxt = x, to = y;}
    }E[N * 21];
    struct stack{
    	int x, y;
    	inline stack(int u = 0, int v = 0){x = u, y = v;}
    }stk[N * 21];
    
    inline void read(int &x)
    {
    	x = 0; char ch = getchar();
    	while (!isdigit(ch)) ch = getchar();
    	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
    }
    
    void update(int p, int l, int r, int tl, int tr, int x)
    {
    	if (tl <= l && r <= tr)
    	{
    		E[++tot] = edge(Q[p], x), Q[p] = tot;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if (tl <= mid) update(ls, l, mid, tl, tr, x);
    	if (tr > mid) update(rs, mid + 1, r, tl, tr, x);
    }
    
    int fa[N], siz[N], d[N], ans[N];
    int find(int x){return (fa[x] == x ? x : find(fa[x]));}
    int getdis(int x)
    {
    	if (x == fa[x]) return d[x];
    	return d[x] ^ getdis(fa[x]);
    }
    
    void solve(int p, int l, int r)
    {
    	int lst = top, flag = 0, mid = (l + r) >> 1;
    	for(re int i = Q[p], x, y, u, v; i; i = E[i].nxt)
    	{
    		x = e[E[i].to].x, y = e[E[i].to].y, u = find(x), v = find(y);
    		if (u ^ v)
    		{
    			if (siz[u] > siz[v]) swap(u, v), swap(x, y);
    			fa[u] = fa[v], d[u] = d[x] ^ d[y] ^ 1, siz[v] += siz[u];
    			stk[++top] = stack(u, v);
    		}
    		else if (!(getdis(x) ^ getdis(y))){flag = 1; break;}
    	}
    	if (flag ^ 1) 
    		if (l ^ r) solve(ls, l, mid), solve(rs, mid + 1, r);
    		else ans[l] = 1;
    	for(int x, y; lst ^ top; --top)
    		x = stk[top].x, y = stk[top].y, fa[x] = x, d[x] = 0, siz[y] -= siz[x];
    }
    
    int main()
    {
    	read(n), read(m), read(k);
    	for(re int i = 1, l, r, x, y; i <= m; i++) 
    		read(x), read(y), read(l), read(r), ++l, ++r, e[i] = node(x, y), update(1, 1, n, l, r - 1, i);
    	for(re int i = 1; i <= n; i++) fa[i] = i, siz[i] = 1;
    	solve(1, 1, k);
    	for(re int i = 1; i <= k; i++) (ans[i] ? printf("Yes
    ") : printf("No
    "));
    }
    
  • 相关阅读:
    javaWeb 使用jsp开发 if else 标签
    javaWeb 使用jsp开发 if 标签
    javaWeb 使用jsp标签进行防盗链
    javaWeb 在jsp中 使用自定义标签输出访问者IP
    javaWeb el表达式和jstl快速入门案例
    javaWeb 使用 jsp 和 javaBean 实现计算器功能
    javaWeb 使用cookie显示上次访问网站时间
    javaWeb 使用cookie显示商品浏览记录
    javaWeb request乱码处理
    ubunu下用命令设置壁纸
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15152209.html
Copyright © 2011-2022 走看看