BZOJ2333 棘手的操作
Description
有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:
U x y: 加一条边,连接第x个节点和第y个节点
A1 x v: 将第x个节点的权值增加v
A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v
A3 v: 将所有节点的权值都增加v
F1 x: 输出第x个节点当前的权值
F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值
F3: 输出所有节点中,权值最大的节点的权值
n.q <= 300000
Solution
这题题号真2333
首先考虑用并查集维护连通性.
单点加, 查. 全局加, 查. 都比较好实现, 主要是联通块维护.
考虑用线段树维护. 但线段树要求的区间是连续的. 如何解决?
考虑做树剖的时候查询子树的dfn是连续的, 我们考虑重新编号.
于是我们把操作离线. 然后先用并查集维护连通性, 把树建出来, 每个集合在合并时,就将这个集合的根节点设置为它的最后一个子树.然后来一波dfs求出每个点的dfs序.
然后就很好做了(我TM竟然没想出来)
因为最终的dfs序已经形成, 所以我们只要把询问重新用线段树模拟计算一遍就好了
注意并查集要维护当前集合的大小, 然后直接在线段树上操作区间$$[dfn[x], dfn[x] + size[x] - 1]$$即可, 然后在实际代码编写中并不要写dfs, 只要在合并集合时将被合并者的线段全体接到目标线段之后.
Inspiration
在维护集合连通性, 因为集合的依附关系可以用一棵树来表示. 所以, 我们如果要对联通块进行修改,查询.可以将操作离线. 再行用并查集森林的dfs序进行重新编号. 即可维护
Code:
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
typedef long long LL;
typedef long double LD;
int read() {
int x = 0, flag = 1;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') flag *= -1;
ch = getchar();
}
while(isdigit(ch)) {
x = (x << 3) + (x << 1) + ch - 48;
ch = getchar();
}
return x * flag;
}
void write(LL a) {
if(a >= 10) write(a / 10);
putchar(a % 10 + '0');
}
#define Maxn 300009
int n, a[Maxn];
int fa[Maxn], nxt[Maxn], tail[Maxn];
int find(int x) {
return x ^ fa[x] ? (fa[x] = find(fa[x])) : x;
}
struct operation {
int id, val1, val2;
}opt[Maxn];
int dfn[Maxn], unid[Maxn], size[Maxn], cnt;
namespace SGMT_tree {
int tree[Maxn << 3], tag[Maxn << 3];
#define lc(x) ((x) << 1)
#define rc(x) (((x) << 1) | 1)
void pushup(int root) {
tree[root] = max(tree[lc(root)], tree[rc(root)]);
}
void pushdown(int root) {
if(tag[root]) {
tree[lc(root)] += tag[root], tree[rc(root)] += tag[root];
tag[lc(root)] += tag[root], tag[rc(root)] += tag[root];
tag[root] = 0;
}
}
void build(int root, int l, int r) {
if(l > r) return ;
if(l == r) {
tree[root] = a[unid[l]];
return ;
}
int mid = (l + r) >> 1;
build(lc(root), l, mid);
build(rc(root), mid + 1, r);
pushup(root);
}
void modify(int root, int l, int r, int x, int y, int v) {
if(l > r || r < x || l > y) return ;
if(x <= l && r <= y) {
tree[root] += v, tag[root] += v;
return ;
}
int mid = (l + r) >> 1; pushdown(root);
modify(lc(root), l, mid, x, y, v);
modify(rc(root), mid + 1, r, x, y, v);
pushup(root);
}
int query(int root, int l, int r, int x, int y) {
if(l > r || r < x || l > y) return INT_MIN;
if(x <= l && r <= y) return tree[root];
int mid = (l + r) >> 1, res = INT_MIN; pushdown(root);
res = max(query(lc(root), l, mid, x, y), res);
res = max(query(rc(root), mid + 1, r, x, y), res);
return res;
}
}
char s[Maxn];
int main() {
#ifdef Qrsikno
freopen("BZOJ2333.in", "r", stdin);
freopen("BZOJ2333.out", "w", stdout);
#endif
n = read();
rep(i, 1, n) a[i] = read();
rep(i, 1, n) fa[i] = tail[i] = i, nxt[i] = 0;
int q = read();
rep(i, 1, q) {
scanf("%s", s);
if(s[0] == 'U') opt[i].id = 0, opt[i].val1 = read(), opt[i].val2 = read();
if(s[0] == 'A') {
if(s[1] == '1') opt[i].id = -1, opt[i].val1 = read(), opt[i].val2 = read();
if(s[1] == '2') opt[i].id = -2, opt[i].val1 = read(), opt[i].val2 = read();
if(s[1] == '3') opt[i].id = -3, opt[i].val1 = read();
}
if(s[0] == 'F') {
if(s[1] == '1') opt[i].id = 1, opt[i].val1 = read();
if(s[1] == '2') opt[i].id = 2, opt[i].val1 = read();
if(s[1] == '3') opt[i].id = 3;
}
}
rep(i, 1, q)
if(!opt[i].id) {
int u = opt[i].val1, v = opt[i].val2, fu = find(u), fv = find(v);
if(fu ^ fv) {
fa[fu] = fv;
nxt[tail[fv]] = fu; tail[fv] = tail[fu];
}
}
rep(i, 1, n)
if(find(i) == i)
for(int j = i; j; j = nxt[j]){
dfn[j] = ++cnt;
unid[cnt] = j;
}
SGMT_tree :: build(1, 1, n);
rep(i, 1, n) fa[i] = tail[i] = i, nxt[i] = 0, size[i] = 1;
rep(i, 1, q) {
if(opt[i].id == 0) {
int u = opt[i].val1, v = opt[i].val2, fu = find(u), fv = find(v);
if(fu ^ fv) {
fa[fu] = fv;
nxt[tail[fv]] = fu; tail[fv] = tail[fu];
size[fv] += size[fu];
}
}
if(opt[i].id == -1) {
SGMT_tree :: modify(1, 1, n, dfn[opt[i].val1], dfn[opt[i].val1], opt[i].val2);
}
if(opt[i].id == -2) {
int u = find(opt[i].val1);
SGMT_tree :: modify(1, 1, n, dfn[u], dfn[u] + size[u] - 1, opt[i].val2);
}
if(opt[i].id == -3) SGMT_tree :: modify(1, 1, n, 1, n, opt[i].val1);
if(opt[i].id == 1) printf("%d\n", SGMT_tree :: query(1, 1, n, dfn[opt[i].val1], dfn[opt[i].val1]));
if(opt[i].id == 2) {
int u = find(opt[i].val1);
printf("%d\n", SGMT_tree :: query(1, 1, n, dfn[u], dfn[u] + size[u] - 1));
}
if(opt[i].id == 3) printf("%d\n", SGMT_tree :: query(1, 1, n, 1, n));
}
#ifdef Qrsikno
cerr << clock() * 1.0 / CLOCKS_PER_SEC << endl;
#endif
return 0;
}
BZOJ2333 棘手的操作的更多相关文章
- 【BZOJ2333】棘手的操作(左偏树,STL)
[BZOJ2333]棘手的操作(左偏树,STL) 题面 BZOJ上看把... 题解 正如这题的题号 我只能\(2333\) 神TM棘手的题目... 前面的单点/联通块操作 很显然是一个左偏树+标记 ( ...
- 【bzoj2333】 [SCOI2011]棘手的操作 可并堆+lazy标记
2016-05-31 21:45:41 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 (学习了黄学长的代码 有如下操作: U x y ...
- 真--可并堆模板--BZOJ2333: [SCOI2011]棘手的操作
n<=300000个点,开始是独立的,m<=300000个操作: 方法一:单点修改.查询,区间修改.查询?等等等等这里修改是块修改不是连续的啊,那就让他连续呗!具体方法:离线后,每次连接两 ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- 2333: [SCOI2011]棘手的操作[写不出来]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1979 Solved: 772[Submit][Stat ...
- 2333: [SCOI2011]棘手的操作[离线线段树]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2325 Solved: 909[Submit][Stat ...
- 2333: [SCOI2011]棘手的操作[我不玩了]
2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1979 Solved: 772[Submit][Stat ...
- BZOJ 2333 【SCOI2011】 棘手的操作
题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹……但是树高严格\(\log\)的可并堆我不会啊……还是离线大法好…… 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...
- 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]
题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...
随机推荐
- activiti eclipse 插件不自动生成png
看下图,是不是很简单?
- ffm算法
www.csie.ntu.edu.tw/~cjlin/papers/ffm.pdf 读书笔记 The effect of feature conjunctions(组合特征) is difficul ...
- C#中泛型方法与泛型接口 C#泛型接口 List<IAll> arssr = new List<IAll>(); interface IPerson<T> c# List<接口>小技巧 泛型接口协变逆变的几个问题
http://blog.csdn.net/aladdinty/article/details/3486532 using System; using System.Collections.Generi ...
- 6 使用Ionic开发天气应用
简介:本节课我们会制作一款天气应用,这款应用允许用户查看当前的天气情况.天气预报以及地点收藏,在模态框内显示日出和日落的数据,使用分页滚动面板显示天气信息,使用侧滑菜单实现导航. 6.1 项目配置 环 ...
- mac WebStorm 破解
摘要:因为想要学习HTML所以需要一个工具,同事推荐了webstorm.下载以后再网上搜破解方法.搜索到一个很简单的. 一.下载链接https://www.jetbrains.com/webstorm ...
- 硬件开发之pcb---PCB抗干扰设计原则
一 电源线布置: 1.电源线.地线的走向应与资料的传递方向一致. 二 地线布置: 1.数字地与模拟地分开. 2.接地线应尽量加粗,致少能通过3倍于印制板上的允许电流,一般应达2~3mm. 3.接地线应 ...
- mac for smartSVN9 (8,9)破解方法 附smartSvn_keygen工具图文
mac for smartSVN9 (8,9)破解方法 附smartSvn_keygen工具 工具文件下载: http://files.cnblogs.com/files/xueshanshan/s ...
- YTU 2558: 游起来吧!超妹!
2558: 游起来吧!超妹! 时间限制: 1 Sec 内存限制: 128 MB 提交: 70 解决: 22 题目描述 夏天到了,无聊的超妹跑到了落雪湖里抓鱼吃.结果,游到湖的正中 央时被湖边保安看 ...
- js的location对象
js的location对象 location基础知识 BOM(浏览器对象模型)中最有用的对象之一就是location,它是window对象和document对象的属性.location对象表示载入窗口 ...
- 并不对劲的bzoj4199: [Noi2015]品酒大会
传送门-> 又称普及大会. 这题没什么好说的……后缀自动机裸题……并不对劲的人太菜了,之前照着标程逐行比对才过了这道题,前几天刚刚把这题一遍写对…… 这题的输出和某两点相同后缀的长度有关,那么把 ...