\(\text{Solution}\)

线段树分治的模板

对时间分治,线段树下标表示时间

在线段树上处理每条覆盖当前区间的边,对当前的时间区间求答案

小区间的信息可以由大区间一路下来得到,那么答案就是叶子节点的答案

对于二分图的加边动态判定,可以用并查集维护

具体来说就是用带权并查集,维护每个点与其父亲点集的异同

因为线段树区间返回时需要撤销并查集操作,那么就打个可撤销并查集按秩合并即可

\(\text{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\n") : printf("No\n"));
}

最新文章

  1. json数据格式及json校验格式化工具简单实现
  2. Win7下VS2008破解方法
  3. Lisp 函数
  4. [BS-28] iOS中分页的几种算法
  5. tp-link便携式路由器固件升级方式
  6. Codeforces Round #FF/#255 D DZY Loves Modification --贪心+优先队列
  7. 03.Hibernate一对多关联
  8. PHP用反撇号(`,也就是键盘上ESC键下面的那个,和~在同一个上面)执行外部命令
  9. JqueryEasyUI 增加选项卡
  10. # Day04-Android
  11. google base 之MessagePumpForUI
  12. ubuntu 使用第一天
  13. 【】小技巧】CSS文字两端对齐
  14. Janus 二元神漏洞测试
  15. EM算法的直观描述
  16. PAT1097:Deduplication on a Linked List
  17. mybatis小结
  18. 前端入门14-JavaScript进阶之继承
  19. Linux - DDOS检测
  20. plsql 查询 卡死问题解决

热门文章

  1. Linux禁止摄像头自动曝光(手动调节曝光)
  2. mybatis中xml的sql之test中文报错
  3. 第三十节:fillder抓取APP数据之小程序
  4. 2.9:数据交换-csv、Excel、json、爬虫、Tushare获取数据
  5. STM32基本定时器控制LED闪烁代码
  6. Java开发网络安全常见问题
  7. Java学习笔记:2022年1月9日(其二)
  8. JS基础简介
  9. Navicat可视化软件及多表查询的方法
  10. python学习第三周总结