棘手的操作(bzoj 2333)
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: 输出所有节点中,权值最大的节点的权值
Input
输入的第一行是一个整数N,代表节点个数。
接下来一行输入N个整数,a[1], a[2], …, a[N],代表N个节点的初始权值。
再下一行输入一个整数Q,代表接下来的操作数。
最后输入Q行,每行的格式如题目描述所示。
Output
对于操作F1, F2, F3,输出对应的结果,每个结果占一行。
Sample Input
0 0 0
8
A1 3 -20
A1 2 20
U 1 3
A2 1 10
F1 3
F2 3
A3 -10
F3
Sample Output
10
10
HINT
对于30%的数据,保证 N<=100,Q<=10000
对于80%的数据,保证 N<=100000,Q<=100000
对于100%的数据,保证 N<=300000,Q<=300000
对于所有的数据,保证输入合法,并且 -1000<=v, a[1], a[2], …, a[N]<=1000
/*
离线+线段树
对于这个题目,有一个棘手的地方是如何对一个连通块内的元素进行操作,如果它们在一个连续的序列就可以了。
我们可以将询问离线,然后用并查集合并就可以了。
*/
#include<iostream>
#include<cstdio>
#define N 300010
#define inf 1000000000
using namespace std;
int n,m,cnt,a[N],w[N],dfn[N];
int next[N],fa[N],ed[N];
int mx[N*],tag[N*];
struct Node{int op,x,y;}q[N];
void pushup(int k){
mx[k]=max(mx[k*],mx[k*+]);
}
void pushdown(int k){
if(!tag[k]) return;
mx[k*]+=tag[k];
mx[k*+]+=tag[k];
tag[k*]+=tag[k];
tag[k*+]+=tag[k];
tag[k]=;
}
void change(int k,int l,int r,int x,int y,int val){
if(l>=x&&r<=y){
mx[k]+=val;
tag[k]+=val;
return;
}
pushdown(k);
int mid=l+r>>;
if(x<=mid) change(k*,l,mid,x,y,val);
if(y>mid) change(k*+,mid+,r,x,y,val);
pushup(k);
}
int query(int k,int l,int r,int x,int y){
if(l>=x&&r<=y) return mx[k];
pushdown(k);
int mid=l+r>>,maxn=-inf;
if(x<=mid) maxn=max(maxn,query(k*,l,mid,x,y));
if(y>mid) maxn=max(maxn,query(k*+,mid+,r,x,y));
return maxn;
}
void build(int k,int l,int r){
if(l==r){
mx[k]=dfn[l];
return;
}
int mid=l+r>>;
build(k*,l,mid);
build(k*+,mid+,r);
pushup(k);
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void merge(int i){
int r1=find(q[i].x),r2=find(q[i].y);
if(r1!=r2){
fa[r2]=r1;next[ed[r1]]=r2;ed[r1]=ed[r2];
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=n;i++) fa[i]=ed[i]=i;
char s[];scanf("%d",&m);
for(int i=;i<=m;i++){
scanf("%s",s);
if(s[]=='U'){
q[i].op=;
scanf("%d%d",&q[i].x,&q[i].y);
merge(i);
}
if(s[]=='A'){
q[i].op=s[]-''+;
scanf("%d",&q[i].x);
if(s[]!='') scanf("%d",&q[i].y);
}
if(s[]=='F'){
q[i].op=s[]-''+;
if(s[]!='') scanf("%d",&q[i].x);
}
}
for(int i=;i<=n;i++)
if(fa[i]==i){
for(int j=i;j;j=next[j]){
w[j]=++cnt;dfn[cnt]=a[j];
}
}
build(,,n);
for(int i=;i<=n;i++) fa[i]=ed[i]=i;
int r;
for(int i=;i<=m;i++){
if(q[i].op==) merge(i);
if(q[i].op==) change(,,n,w[q[i].x],w[q[i].x],q[i].y);
if(q[i].op==) r=find(q[i].x),change(,,n,w[r],w[ed[r]],q[i].y);
if(q[i].op==) change(,,n,,n,q[i].x);
if(q[i].op==) printf("%d\n",query(,,n,w[q[i].x],w[q[i].x]));
if(q[i].op==) r=find(q[i].x),printf("%d\n",query(,,n,w[r],w[ed[r]]));
if(q[i].op==) printf("%d\n",query(,,n,,n));
}
return ;
}
棘手的操作(bzoj 2333)的更多相关文章
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- BZOJ 2333 【SCOI2011】 棘手的操作
题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹……但是树高严格\(\log\)的可并堆我不会啊……还是离线大法好…… 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...
- BZOJ 2333: [SCOI2011]棘手的操作
题目描述 真的是个很棘手的操作.. 注意每删除一个点,就需要clear一次. #include<complex> #include<cstdio> using namespac ...
- 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 ...
- 【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 ...
- 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]
题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...
随机推荐
- OracleWeblogic12C安装教程
一,安装WebLogic Server 1. 双击exe安装文件 2.准备安装文件 3. 生成向导序列 4. 选择安装路径 5. 开始安装 经过以上步骤,weblogic已经成功安装到了你的电脑上,但 ...
- python学习之循环语句
编程语言中的循环语句,以循环判断达式是否成立为条件,若表达式成立则循环执行该表达式,若不成立则跳出当前执行执行语句且继续执行其后代码. 如下图所示. Python中提供以下循环方式 循环类型 描述 w ...
- Postgres常用命令之增、删、改、查
增.删.改.查: postgres=# \password postgres 为postgres进行密码设置: postgres=# CREATE USER test WITH PASSWORD '1 ...
- 5 Django-1的路由层(URLconf)
URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码 ...
- nodejs基础1
nodejs学习网站: https://github.com/alsotang/node-lessons 1.全局对象 (1)node中没有window对象,有global对象替代window对象 g ...
- 《Cracking the Coding Interview》——第17章:普通题——题目12
2014-04-29 00:04 题目:给定一个整数数组,找出所有加起来为指定和的数对. 解法1:可以用哈希表保存数组元素,做到O(n)时间的算法. 代码: // 17.12 Given an arr ...
- php jsonp单引号转义
php中jsonp输出时一般用下面的格式: callbackname('json string'); 如果中间的json string中含有单引号,这个输出就是有问题的,调用方一般是无法处理的,所以我 ...
- 利用Xtrabackup搭建GTID主从复制(一主一从)
Preface I've been demonstrated how to implement a master-slave structure using mysqldump in ...
- 孤荷凌寒自学python第十七天初识Python的函数
孤荷凌寒自学python第十七天初识Python的函数 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 函数是能够完成指定运算并返回运算结果的代码块.是结构化编程重要的结构. 我首先发现pyt ...
- python import模块熟悉方法
python import导入的可用模块很多,新增速度较快,无法一次性全部掌握. 掌握熟悉一种模块的方法是非常有价值的技能. 探究模块可以从python解释器入手,具体流程记录如下: 以os模块为例: ...