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. <Docker学习>3. docker镜像命令使用

    镜像提供容器运行时所需要的程序,资源.配置文件等,是一个特殊的文件系统.是容器运行的基础.镜像是多层文件系统组成的,是一个分层存储的架构,在镜像的构建中,会一层层的构建,每一层构建完成就不会发生改变, ...

  2. POJ:2236-Wireless Network

    Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 34265 Accepted: 14222 D ...

  3. perl语言入门总结-第4章-子程序

    子程序定义和返回值 sub sum{ print "调用了子程序\n"; $a + $b; #后一行为返回值 } ; ; $s =∑ #34 调用子程序 子程序中的参数,参数固定( ...

  4. Mplab X IDE 安装DMCI

     DMCI在Mplab 8中是默认安装的,在 Mplab X IDE中是作为插件,默认不安装.   找到     勾选前面的复选框,点击安装

  5. BZOJ 5004: 开锁魔法II

    比较显然 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; i ...

  6. win32 signal

    Remarks   The signal function enables a process to choose one of several ways to handle an interrupt ...

  7. centos使用--开机启动

    centos6.8 1.利用 chkconfig 来配置启动级别 在CentOS或者RedHat其他系统下,如果是后面安装的服务,如httpd.mysqld.postfix等,安装后系统默认不会自动启 ...

  8. SDWebImage实现原理(怎么实现图片缓存器)

    入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处 ...

  9. Java基础-1简单了解与原理

    简单了解: Java看起来设计得很像C++,但是为了使语言小和容易熟悉,设计者们把C++语言中许多可用的特征去掉了,这些特征是一般程序员很少使用的.因为Java没有结构,数组和串都是对象,所以不需要指 ...

  10. React03 移动端跨平台开发

    目录 React-day03 RN移动端开发 了解React-Native 了解React-Native工作流程 创建第一个React-Native项目 * 了解React-Native项目及结构 开 ...