Description

给一个 \(n\) 个点 \(m\) 条边的、不含偶环的无向图,每次询问 \([l,r]\) ,求 \([l,r]\) 中有多少 \([x,y]\) 使得编号在 \([x,y]\) 中的点组成的诱导子图是一个二分图。

\(n,m,q\le 3\times 10^5\)

Solution

显然这个图是一个奇环仙人掌。于是在这张图中,是二分图的充要条件是不含环。

于是预处理边双连通分量,记录每个 \(ebc\) 的编号最小和最大点,记为 \(mn[i]\) 和 \(mx[i]\) 。

那么就可以记录一个数组 \(s[i]\) ,表示编号为 \(i\) 的点向右最远可以可以扩展到 \(s[i]\) ,使得 \([i,s[i]]​\) 的点组成的诱导子图是二分图。

所以初始 \(s[mn[i]]=mx[i] - 1\) ,再用一个后缀最小值就可以得到 \(s\) 数组。显然 \(s\) 单调不减。

考虑如何回答询问。考虑一个中转点 \(p\) ,满足 \(\forall i \in [l,p-1],s[i]<r\) 以及 \(\forall i\in[p,r],s[i]>=r\) ,那么答案等于
\[ (\sum_{i=l}^{p-1}s[i]-i+1)+(\sum_{i=p}^rr-i+1) \]

#include<bits/stdc++.h>
using namespace std;template <class T> void read(T &x) {x = 0; bool flag = 0; char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) flag |= ch == '-';for (; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - 48; flag ? x = ~x + 1 : 0;
}#define N 300010
#define rep(i, a, b) for (auto i = (a); i <= (b); i++)
#define drp(i, a, b) for (auto i = (a); i >= (b); i--)
#define ll long longstruct { int v, next; }e[N << 1];
int head[N];
bool isBridge[N << 1];
inline void add(int u, int v) {static int tot = 1; e[++tot].v = v, e[tot].next = head[u], head[u] = tot;
}int dfn[N], low[N];
void tarjan(int u, int fa) {static int ind; dfn[u] = low[u] = ++ind;for (int i = head[u], v; i; i = e[i].next) {if (!dfn[v = e[i].v]) {tarjan(v, u), low[u] = min(low[u], low[v]);if (low[v] > dfn[u]) isBridge[i] = isBridge[i ^ 1] = 1;}else if (dfn[v] < dfn[u] && v ^ fa) low[u] = min(low[u], dfn[v]);}
}int bl[N], siz[N];
void dfs(int u, int ebc) {siz[bl[u] = ebc]++;
//  printf("%d\n", u);for (int i = head[u]; i; i = e[i].next) if (!bl[e[i].v] && !isBridge[i]) dfs(e[i].v, ebc);
}int mn[N], mx[N], s[N];
ll sum[N];int main() {int n, m; read(n), read(m);rep(i, 1, m) {int u, v; read(u), read(v);add(u, v), add(v, u);}rep(i, 1, n) if (!dfn[i]) tarjan(i, 0);int ebc = 0;rep(i, 1, n) if (!bl[i]) dfs(i, ++ebc);rep(i, 1, n) mx[bl[i]] = i;drp(i, n, 1) mn[bl[i]] = i;rep(i, 1, n) s[i] = n;rep(i, 1, ebc) if (siz[i] > 1) s[mn[i]] = mx[i] - 1;drp(i, n - 1, 1) s[i] = min(s[i], s[i + 1]);rep(i, 1, n) sum[i] = sum[i - 1] + s[i] - i + 1;int q; read(q);while (q--) {int l, r; read(l), read(r);int p = lower_bound(s + l, s + r + 1, r) - s;printf("%lld\n", 1ll * (r - p + 1) * (r - p + 2) / 2 + sum[p - 1] - sum[l - 1]);}return 0;
}

转载于:https://www.cnblogs.com/aziint/p/9643134.html

CodeForces 901C Bipartite Segments相关推荐

  1. Bipartite Segments CodeForces - 901C (区间二分图计数)

    大意: 给定无向图, 无偶环, 每次询问求[l,r]区间内, 有多少子区间是二分图. 无偶环等价于奇环仙人掌森林, 可以直接tarjan求出所有环, 然后就可以预处理出每个点为右端点时的答案. 这样的 ...

  2. 苹果电脑连linux密码错误,Mac系统登录不进系统解决办法

    1.找到买苹果电脑时附带的 Mac OS X 系统光盘,或者有苹果 Mac OS X 系统镜像的 U 盘/移动硬盘,塞入光驱(或插在 USB /火线接口上).重启苹果电脑,开机时按住"opt ...

  3. Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树扫描线

    D. Vika and Segments 题目连接: http://www.codeforces.com/contest/610/problem/D Description Vika has an i ...

  4. Codeforces Round #245 (Div. 1) E. Points and Segments 欧拉回路 + 建模

    传送门 文章目录 题意: 思路: 题意: 思路: 考虑对于线段,如何建模. 我们考虑先将线段转换成左闭右开的形式,将左右点连起来. 再考虑每个点,将所有离散化后的点拿出来,每个点都有一个度,现在问题就 ...

  5. Codeforces Round #636 (Div. 3) F. Restore the Permutation by Sorted Segments 思维 + 暴力

    传送门 文章目录 题意: 思路: 题意: n≤200n\le200n≤200 思路: 首先关注到rrr从[2,n][2,n][2,n]都出现一次,所以很明显最后一个位置只出现一次,但是这样倒着来不是很 ...

  6. codeforces 610D D. Vika and Segments(离散化+线段树+扫描线算法)

    题目链接: D. Vika and Segments time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  7. Codeforces 1196B Odd Sum Segments

    https://codeforces.com/contest/1196/problem/B 题解:贪心 /* *@Author: STZG *@Language: C++ */ #include &l ...

  8. Too Many Segments (hard version) CodeForces - 1249D2(贪心+容器vector+set)

    题目 给多组线段,而每一个点的覆盖次数不超过K,每次可去除一个线段,问最少去多少线段以及线段的位置. The only difference between easy and hard version ...

  9. Too Many Segments (easy version) CodeForces - 1249D1(贪心+差分)

    题意 给多组线段,而每一个点的覆盖次数不超过K,每次可去除一个线段,问最少去多少线段以及线段的位置. The only difference between easy and hard version ...

最新文章

  1. 《算法竞赛进阶指南》打卡-基本算法-AcWing 90. 64位整数乘法:位运算
  2. AlertDialog(对话框)的基本使用
  3. 【实验手册】使用Visual Studio Code 开发.NET Core应用程序
  4. ”语义分割”中的“语义”
  5. Objective-C(9)内存管理之ARC
  6. 修改Jupyter Notebook的默认路径
  7. layui table 复选框数据_Python操作三大数据库 Mysql
  8. jumpserver的安装
  9. 狂神说shiro案例源码
  10. catia中的螺旋伞齿轮画法_聚焦:螺旋伞齿轮画法要领
  11. 安卓 java hook 免root_[原创]利用VirtualApp实现免Root注入Hook(一)
  12. 公众号头条文章数据接口 API
  13. 百度地图爬虫——获取某区域所有中学附近的网吧数据
  14. 什么是WMS系统,WMS如何选型
  15. WCF 会话服务 Session
  16. 输入手机号获取验证码的注册页面,说出测试过程
  17. php 小程序 运动步数_【小程序+ thinkphp5】 获取微信运动数据
  18. 使用GAN的图像超分辨率功能彻底消灭模糊图
  19. 产品经理的修炼:怎样把梳子卖给和尚
  20. PowerBuilder DeCompiler(PB DeCompiler) Demo download(PB反编译,支持5-12)

热门文章

  1. Win10自带的邮件客户端配置腾讯企业邮箱账号
  2. k8s使用kubectl命令部署nginx并以nodeport方式暴露端口
  3. Java的agent机制简述
  4. windows下使用curl以及常用curl命令
  5. 解决导入的maven聚合工程中子模块项目不显示
  6. oracle绑定主键,oracle添加主键的四种方法:
  7. 外循环java作用_循环和外循环的区别和作用
  8. 多服务监听Redis key失效通知,并指定特定机器进行处理业务
  9. linux打开bash后报错:~/.bashrc: 没有那个文件或目录
  10. 记录gulp报错The following tasks did not complete: cssmin或类似任务