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

3

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

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)的更多相关文章

  1. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)

    2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...

  2. 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树|可并堆-左偏树)

    2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...

  3. BZOJ 2333 【SCOI2011】 棘手的操作

    题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹……但是树高严格\(\log\)的可并堆我不会啊……还是离线大法好…… 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...

  4. BZOJ 2333: [SCOI2011]棘手的操作

    题目描述 真的是个很棘手的操作.. 注意每删除一个点,就需要clear一次. #include<complex> #include<cstdio> using namespac ...

  5. 2333: [SCOI2011]棘手的操作[写不出来]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1979  Solved: 772[Submit][Stat ...

  6. 2333: [SCOI2011]棘手的操作[离线线段树]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2325  Solved: 909[Submit][Stat ...

  7. 2333: [SCOI2011]棘手的操作[我不玩了]

    2333: [SCOI2011]棘手的操作 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1979  Solved: 772[Submit][Stat ...

  8. 【BZOJ2333】棘手的操作(左偏树,STL)

    [BZOJ2333]棘手的操作(左偏树,STL) 题面 BZOJ上看把... 题解 正如这题的题号 我只能\(2333\) 神TM棘手的题目... 前面的单点/联通块操作 很显然是一个左偏树+标记 ( ...

  9. 【bzoj2333】 [SCOI2011]棘手的操作 可并堆+lazy标记

    2016-05-31  21:45:41 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 (学习了黄学长的代码 有如下操作: U x y ...

  10. 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]

    题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...

随机推荐

  1. OracleWeblogic12C安装教程

    一,安装WebLogic Server 1. 双击exe安装文件 2.准备安装文件 3. 生成向导序列 4. 选择安装路径 5. 开始安装 经过以上步骤,weblogic已经成功安装到了你的电脑上,但 ...

  2. python学习之循环语句

    编程语言中的循环语句,以循环判断达式是否成立为条件,若表达式成立则循环执行该表达式,若不成立则跳出当前执行执行语句且继续执行其后代码. 如下图所示. Python中提供以下循环方式 循环类型 描述 w ...

  3. Postgres常用命令之增、删、改、查

    增.删.改.查: postgres=# \password postgres 为postgres进行密码设置: postgres=# CREATE USER test WITH PASSWORD '1 ...

  4. 5 Django-1的路由层(URLconf)

    URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个URL调用哪一段逻辑代码 ...

  5. nodejs基础1

    nodejs学习网站: https://github.com/alsotang/node-lessons 1.全局对象 (1)node中没有window对象,有global对象替代window对象 g ...

  6. 《Cracking the Coding Interview》——第17章:普通题——题目12

    2014-04-29 00:04 题目:给定一个整数数组,找出所有加起来为指定和的数对. 解法1:可以用哈希表保存数组元素,做到O(n)时间的算法. 代码: // 17.12 Given an arr ...

  7. php jsonp单引号转义

    php中jsonp输出时一般用下面的格式: callbackname('json string'); 如果中间的json string中含有单引号,这个输出就是有问题的,调用方一般是无法处理的,所以我 ...

  8. 利用Xtrabackup搭建GTID主从复制(一主一从)

      Preface       I've been demonstrated how to implement a master-slave structure using mysqldump in ...

  9. 孤荷凌寒自学python第十七天初识Python的函数

    孤荷凌寒自学python第十七天初识Python的函数 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 函数是能够完成指定运算并返回运算结果的代码块.是结构化编程重要的结构. 我首先发现pyt ...

  10. python import模块熟悉方法

    python import导入的可用模块很多,新增速度较快,无法一次性全部掌握. 掌握熟悉一种模块的方法是非常有价值的技能. 探究模块可以从python解释器入手,具体流程记录如下: 以os模块为例: ...