传送门 洛谷p4230

题意大概是这样,有m条无向边按输入顺序标号,如果一段区间[l,r][l,r][l,r]上的无向边包含环就称区间[l,r][l,r][l,r]是“加强区间”,求每条边分别在多少个“加强区间”内。

设ans[i]ans[i]ans[i]表示第iii条边在多少个加强区间内。我们可以换个视角:如果我们能找出所有“加强区间”,那么就只要给每个加强区间上的ans" role="presentation" style="position: relative;">ansansans值都增加111就好了。

那么如何找出所有“加强区间”?我们有个老套路:枚举左端点,查询右端点。

然而当左端点固定的时候 右端点不止一个,真要把所有加强区间都找出来应该是不现实的(而且应该是O(n2)" role="presentation" style="position: relative;">O(n2)O(n2)O(n^2)的)

但是可以发现一个很好的性质:如果[l,r][l,r][l,r]是加强区间,那么对于所有r≤r′≤mr≤r′≤mr\leq r'\leq m,区间[l,r′][l,r′][l,r']都是加强区间。

于是可以考虑枚举左端点lll,查找最小的右端点r" role="presentation" style="position: relative;">rrr,然后记录答案(一会再讲怎么记录)

但是很显然这个右端点没法很快地找出来,似乎还需要一个性质

我们发现:随着lll的递增,最小的右端点r" role="presentation" style="position: relative;">rrr单调不减。

有了这个性质,我们就可以双指针辣!用lct来加边删边,时间复杂度O(mlogn)O(mlogn)O(mlogn)。

然后来说一说怎么得到答案。每次找到一个加强区间[l,r][l,r][l,r]的时候,意味着[l,r],[l,r+1],[l,r+2],...,[l,m][l,r],[l,r+1],[l,r+2],...,[l,m][l,r], [l,r+1], [l,r+2], ..., [l,m]都是加强区间,因此我们需要给ans[l],ans[l+1],...,ans[r]ans[l],ans[l+1],...,ans[r]ans[l],ans[l+1],...,ans[r]都加上m−r+1m−r+1m-r+1(即首项为m−r+1m−r+1m-r+1,公差为000的等差数列),然后给[r+1,m]" role="presentation" style="position: relative;">[r+1,m][r+1,m][r+1,m]加上一个首项为m−rm−rm-r,公差为−1−1-1的等差数列。

如果把等差数列差分,就会发现区间加等差的操作变成了区间加。线段树?当然不需要。因为如果把差分数列再差分(二阶差分),区间加就变成了单点加。(这里可以自己推一下)最终统计答案的时候可以先求出一阶差分再求出原数列,比较方便了。

(感觉话有点多)

#include <cctype>
#include <cstdio>
#include <climits>
#include <algorithm>template <typename T> inline void read(T& t) {int f = 0, c = getchar(); t = 0;while (!isdigit(c)) f |= c == '-', c = getchar();while (isdigit(c)) t = t * 10 + c - 48, c = getchar();if (f) t = -t;
}
template <typename T, typename... Args>
inline void read(T& t, Args&... args) {read(t); read(args...);
}#ifdef WIN32
#define LLIO "%I64d"
#else
#define LLIO "%lld"
#endif  // WIN32 long long
#define rep(I, A, B) for (int I = (A); I <= (B); ++I)
#define rrep(I, A, B) for (int I = (A); I >= (B); --I)
#define erep(I, X) for (int I = head[X]; I; I = next[I])const int maxn = 4e5 + 207;
int fa[maxn], ch[maxn][2];
bool rev[maxn];
int m;inline int iden(int x) {if (ch[fa[x]][0] == x) return 0;if (ch[fa[x]][1] == x) return 1;return -1;
}
inline void rotate(int x) {if (!x) return;int d = iden(x), y = fa[x];if (~iden(y)) ch[fa[y]][iden(y)] = x;fa[x] = fa[y];if ((ch[y][d] = ch[x][d ^ 1]))fa[ch[x][d ^ 1]] = y;fa[ch[x][d ^ 1] = y] = x;
}
inline void pushdown(int x) {if (rev[x]) {rev[ch[x][0]] ^= 1;rev[ch[x][1]] ^= 1;rev[x] = 0; std::swap(ch[x][0], ch[x][1]);}
}
int s[maxn];
inline void splay(int x) {int t = 0;for (int i = x; ; i = fa[i]) {s[++t] = i;if (!~iden(i)) break;}while (t) pushdown(s[t--]);while (~iden(x)) {int y = fa[x];if (~iden(y)) rotate(iden(y) ^ iden(x) ? x : y);rotate(x);}
}
inline void access(int x) {for (int y = 0; x; x = fa[y = x])splay(x), ch[x][1] = y;
}
inline void makeroot(int x) {access(x); splay(x); rev[x] ^= 1;
}
inline void link(int x, int y) {makeroot(x); fa[x] = y;
}
inline void cut(int x, int y) {makeroot(x); access(y); splay(y);fa[x] = ch[y][0] = 0;
}
inline int findroot(int x) {access(x); splay(x);while (pushdown(x), ch[x][0]) x = ch[x][0];splay(x);return x;
}
inline bool connected(int x, int y) {return findroot(x) == findroot(y);
}struct Edge {int x, y;
};
Edge e[maxn];
template <> inline void read<Edge>(Edge& ee) {read(ee.x, ee.y);
}long long d2[maxn], d1[maxn], ans[maxn];
inline void add(int l, int r, int a1, int d) {if (l > r) return;d2[l] += a1;d2[l + 1] += d - a1;d2[r + 1] -= a1 + 1ll * (r - l + 1) * d;d2[r + 2] += a1 + 1ll * (r - l) * d;
}int main() {read(m);rep(i, 1, m) read(e[i]);for (int l = 1, r = 0; l <= m; ++l) {bool found = 0;while (r < m) {++r;if (connected(e[r].x, e[r].y)) {found = 1;break;}link(e[r].x, e[r].y);}if (found) {add(l, r, m - r + 1, 0);add(r + 1, m, m - r, -1);--r;} else break;cut(e[l].x, e[l].y);}rep(i, 1, m) d1[i] = d1[i - 1] + d2[i];rep(i, 1, m) ans[i] = ans[i - 1] + d1[i];rep(i, 1, m) printf(LLIO " ", ans[i]);puts("");return 0;
}

洛谷p4230 连环病原体 题解相关推荐

  1. [luogu P4230]连环病原体

    [luogu P4230] 连环病原体 题意 给定一个长度为 \(n\) 的边序列, 当这个序列的一个子区间内的边都加入图中时产生了环则称其为"加强区间", 求序列中的每条边在多少 ...

  2. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  3. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  4. 洛谷P1273 有线电视网 题解

    洛谷P1273 有线电视网 题解 题目链接:P1273 有线电视网 题意: 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为 ...

  5. 洛谷P4568 [JLOI2011] 飞行路线 题解

    洛谷P4568 [JLOI2011] 飞行路线 题解 题目链接:P4568 [JLOI2011] 飞行路线 题意: Alice 和 Bob 现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公 ...

  6. 洛谷P3426 [POI2005]SZA-Template 题解

    洛谷P3426 [POI2005]SZA-Template 题解 题目链接:P3426 [POI2005]SZA-Template 题意:你打算在纸上印一串字母. 为了完成这项工作,你决定刻一个印章. ...

  7. 洛谷P1156 垃圾陷阱 题解浅谈刷表法与填表法

    洛谷P1156 垃圾陷阱 题解&浅谈刷表法与填表法 填表法 :就是一般的动态规划,当前点的状态,可以直接用状态方程,根据之前点的状态推导出来. 刷表法:由当前点的状态,更新其他点的状态.需要注 ...

  8. 洛谷P1262 间谍网络题解

    洛谷P1262 间谍网络题解 题目大意 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果 A 间谍手中掌握着关于 B 间谍的犯罪证据,则称 A 可以揭发 B.有些间谍收受贿赂,只要 ...

  9. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

最新文章

  1. List Set Map的区别
  2. 【机器学习基础】一文详尽之支持向量机(SVM)算法!
  3. 看一次广告听30分钟歌 你愿意为QQ音乐新功能买单吗?
  4. ae预览不了多次_AE不能预览全部视频的原因分析及解决方案
  5. 求出数组中超过一半的数
  6. Apache Flume的介绍安装及简单案例
  7. Hadoop(十二)MapReduce概述
  8. 怎样填充潘通颜色_怎样判定润滑脂,锂基脂的好坏?
  9. linux安装weblogic界面,Weblogic11g 安装Linux下无Weblogic安装图形界面
  10. QGIS Server安装教程
  11. 【C语言】基于51/52单片机实现楼梯灯控制程序
  12. 送一首诗给心急的、望子成龙的父母们——《牵一只蜗牛去散步》
  13. 机器人学与OROCOS-KDL(一)简介
  14. 3.2 Processing实用调色教程:HSB模式与颜色插值
  15. Windows 10系统用FileZilla Server 1.6.1搭建FTP服务器
  16. 怎么主动发起话题_聊天怎么开启话题?学会这四点,再也不担心尴尬开场
  17. Android-Dex分包最全总结:含Facebook解决方案,移动app开发
  18. Android跑马灯效果
  19. 【连续签到领金币】解题思路总结
  20. App应用接口版本兼容设计和使用原则

热门文章

  1. NDIS函数大全手册
  2. 建筑施工与管理计算机综合应用能力实训报告,建筑施工管理计算机综合应用能力实训报告...
  3. 思科路由器开启DNS解析
  4. 正在励志奋斗的人十大特征
  5. linux系统安装nacos(减少踩坑)并设置开机自动
  6. 九、Unity编辑器开发之Gizmos
  7. Fractal Streets||分形之城
  8. WebStorm 2016.3.1 版本激活方法
  9. 将自定义程序写入U盘引导区,并在真机执行
  10. php 读取mysql 返回xml_用php解析xml并保存到mysql