• P5787 二分图 /【模板】线段树分治


    题目描述

    神犇有一个 nn 个节点的图。

    因为神犇是神犇,所以在 kk 时间内有 mm 条边会出现后消失。

    神犇要求出每一时间段内这个图是否是二分图。

    这么简单的问题神犇当然会做了,于是他想考考你。

    原 BZOJ4025。

    输入格式

    第一行三个整数 n,m,kn,m,k。

    接下来 mm 行,每行四个整数 x,y,l,rx,y,l,r,表示有一条连接 x,yx,y 的边在 ll 时刻出现 rr 时刻消失。

    输出格式

    kk 行,第 ii 行一个字符串 Yes 或 No,表示在第 ii 时间段内这个图是否是二分图。

    输入输出样例

    输入 #1
    3 3 3
    1 2 0 2
    2 3 0 3
    1 3 1 2
    
    输出 #1
    Yes
    No
    Yes
    

    说明/提示

    样例说明

    00 时刻,出现两条边 (1,2)(1,2) 和 (2,3)(2,3)。

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

    11 时刻,出现一条边 (1,3)(1,3)。

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

    22 时刻,(1,2)(1,2) 和 (1,3)(1,3) 两条边消失。

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

    数据范围

    n,k = 10^5n,k=105,m = 2 imes 10^5m=2×105。1 le x,y le n1x,yn,0 le l le r le k0lrk。

    注意

    本题设有 hack 数据(Subtask 22),计 00 分,但若没有通过 hack 数据则不算通过本题。

    题解

    线段树分治康复,代码有注释

    代码

     1 //每个操作都有一段存在的时间,将所有操作拆分并覆盖到线段树上。
     2 //DFS线段树,进入节点的时候加入所有这些节点的操作,出节点的时候撤销这些操作,DFS到叶子的时候统计一下答案。 
     3 #include<bits/stdc++.h>
     4 #define N (100009)
     5 using namespace std;
     6 int n,m,k,fa[N<<1],dep[N<<1],top;
     7 vector<pair<int,int> > e[N<<2];
     8 pair<int,int>st[N<<1];
     9 void Update(int now,int l,int r,int l1,int r1,int x,int y) {
    10     if (l>r1 || r<l1) return;
    11     if (l1<=l && r<=r1) {
    12         e[now].push_back(make_pair(x,y));
    13         return;
    14     }
    15     int mid=(l+r)>>1;
    16     Update(now<<1,l,mid,l1,r1,x,y);
    17     Update(now<<1|1,mid+1,r,l1,r1,x,y);
    18 }
    19 int Find(int x) {
    20     return x==fa[x]?x:Find(fa[x]);
    21 }
    22 void Merge(int fx,int fy) {
    23     if (dep[fx]>dep[fy]) swap(fx,fy);
    24     fa[fx]=fy; dep[fy]+=(dep[fx]==dep[fy]);
    25     st[++top]=make_pair(fx,fy);
    26 }//按秩合并并查集,用栈存历史操作,方便撤销
    27 void DFS(int now,int l,int r,int flag) {
    28     int mid=(l+r)>>1, tmp=top;
    29     for (int i=0; i<e[now].size(); ++i) {
    30         int x=e[now][i].first, y=e[now][i].second;
    31         int fx=Find(x), fy=Find(y), fx_=Find(x+n), fy_=Find(y+n);
    32         if (fx==fy) {
    33             flag=0;
    34             break;
    35         }
    36         Merge(fx,fy_); Merge(fy,fx_);
    37     }
    38     if (l<r) DFS(now<<1,l,mid,flag), DFS(now<<1|1,mid+1,r,flag);
    39     else puts(flag?"Yes":"No");
    40     for (int i=top; i>tmp; --i) {
    41         int fx=st[i].first, fy=st[i].second;
    42         fa[fx]=fx; dep[fy]-=(dep[fx]+1==dep[fy]);
    43     }
    44     top=tmp;
    45 }//并查集判断二分图,加入边(x,y)时若x和y在一个集合就不能构成二分图,否则能构成且合并(x,y'),(x',y)
    46 int main() {
    47     cin>>n>>m>>k;
    48     for (int i=1; i<=2*n; ++i) fa[i]=i, dep[i]=1;
    49     for (int i=1; i<=m; ++i) {
    50         int x,y,l,r;
    51         cin>>x>>y>>l>>r;
    52         Update(1,0,k-1,l,r-1,x,y);
    53     }
    54     DFS(1,0,k-1,1);
    55 }
  • 相关阅读:
    Vue 2.x windows环境下安装
    VSCODE官网下载缓慢或下载失败 解决办法
    angular cli 降级
    Win10 VS2019 设置 以管理员身份运行
    XSHELL 连接 阿里云ECS实例
    Chrome浏览器跨域设置
    DBeaver 执行 mysql 多条语句报错
    DBeaver 连接MySql 8.0 报错 Public Key Retrieval is not allowed
    DBeaver 连接MySql 8.0报错 Unable to load authentication plugin 'caching_sha2_password'
    Linux系统分区
  • 原文地址:https://www.cnblogs.com/refun/p/15066470.html
Copyright © 2020-2023  润新知