2333: [SCOI2011]棘手的操作

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2325  Solved: 909
[Submit][Status][Discuss]

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

Source

线段树+离线操作。

  先离线所有询问,对于所有的U操作先进性预处理,按照读入的顺序用并查集把一个连通块内的点并到一起,并不断的更新每个连通块的最后一个节点。然后按照每个连通块的顺序,把同一个连通块中的节点放到一起,然后用线段树维护。

#include<cstdio>
#include<iostream>
#define lc k<<1
#define rc k<<1|1
using namespace std;
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int N=3e5+;
const int M=N<<;
int n,m,cnt,a[N],dfn[N],w[N];
int fa[N],ed[N],next[N];
int mx[M],de[M];
struct unline{int x,y,op;}q[N];
inline void update(int k){
mx[k]=max(mx[lc],mx[rc]);
}
inline void pushdown(int k){
if(!de[k]) return ;
mx[lc]+=de[k];
mx[rc]+=de[k];
de[lc]+=de[k];
de[rc]+=de[k];
de[k]=;
}
void build(int k,int l,int r){
if(l==r){mx[k]=dfn[l];return ;}
int mid=l+r>>;
build(lc,l,mid);
build(rc,mid+,r);
update(k);
}
void change(int k,int l,int r,int x,int y,int v){
if(l==x&&r==y){
mx[k]+=v;
de[k]+=v;
return ;
}
pushdown(k);
int mid=l+r>>;
if(y<=mid) change(lc,l,mid,x,y,v);
else if(x>mid) change(rc,mid+,r,x,y,v);
else change(lc,l,mid,x,mid,v),change(rc,mid+,r,mid+,y,v);
update(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>>;
if(y<=mid) return query(lc,l,mid,x,y);
else if(x>mid) return query(rc,mid+,r,x,y);
else return max(query(lc,l,mid,x,mid),query(rc,mid+,r,mid+,y));
update(k);
}
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
inline void merge(int i){
int r1,r2;
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(){
n=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++) fa[i]=ed[i]=i;
m=read();char s[];
for(int i=;i<=m;i++){
scanf("%s",s);
if(s[]=='U'){
q[i].op=;
q[i].x=read();q[i].y=read();
merge(i);
}
if(s[]=='A'){
q[i].op=s[]-''+;
q[i].x=read();
if(s[]!='') q[i].y=read();
}
if(s[]=='F'){
q[i].op=s[]-''+;
if(s[]!='') q[i].x=read();
}
}
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;
for(int i=,r;i<=m;i++){
if(q[i].op==) {merge(i);continue;}
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 ;
}

2333: [SCOI2011]棘手的操作[离线线段树]的更多相关文章

  1. BZOJ 2333 棘手的操作(离线+线段树+带权并查集)

    这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...

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

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

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

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

  4. BZOJ 2333: [SCOI2011]棘手的操作 可并堆 左偏树 set

    https://www.lydsy.com/JudgeOnline/problem.php?id=2333 需要两个结构分别维护每个连通块的最大值和所有连通块最大值中的最大值,可以用两个可并堆实现,也 ...

  5. 【bzoj2333 & luoguP3273】棘手的操作(线段树合并)

    题目传送门:bzoj2333 luoguP3273 这操作还真“棘手”..听说这题是可并堆题?然而我不会可并堆.于是我就写了线段数合并,然后调了一晚上,数据结构毁一生!!!QAQ…… 其实这题也可以把 ...

  6. P3273-[SCOI2011]棘手的操作【线段树,并查集】

    正题 题目链接:https://www.luogu.com.cn/problem/P3273 题目大意 \(n\)个点有权值,要求支持操作 连接两个点 单点加权 联通块加权 全图加权 单点询问 联通块 ...

  7. 洛谷.3273.[SCOI2011]棘手的操作(左偏树)

    题目链接 还是80分,不是很懂. /* 七个操作(用左偏树)(t2表示第二棵子树): 1.合并:直接合并(需要将一个t2中原有的根节点删掉) 2.单点加:把这个点从它的堆里删了,加了再插入回去(有负数 ...

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

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

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

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

随机推荐

  1. Nginx安装 默认虚拟主机 Nginx用户认证 Nginx域名重定向

    Nginx安装 cd /usr/local/src (http://nginx.org/en/download.html) wget http://nginx.org/download/nginx-1 ...

  2. 基于PHP采集数据入库程序(二)

    在上篇基于PHP采集数据入库程序(一) 中提到采集新闻信息页的列表数据,接下来讲讲关于采集新闻具体内容 这是上篇博客的最终数据表截图: 接下来要做的操作就是从数据库中读取所需要采集的URL,进行页面抓 ...

  3. PHP多文件上传操作

    在前一篇文章里讲到了关于PHP文件上传原理和简单操作举例是单文件上传. http://www.cnblogs.com/lichenwei/p/3879566.html 其实多文件上传和单文件上传大同小 ...

  4. ambari HDFS-HA 回滚

    curl -u admin:admin -H "X-Requested-By: ambari" -X GET http://zwshen86:8080/api/v1/cluster ...

  5. smartgit 需要输入序列号解决办法

    找到路径: %APPDATA%\syntevo\SmartGit\<main-smartgit-version> 然后删除: settings.xml 再重新打开smartgit 就可以了

  6. 安装程序配置服务器失败。参考服务器错误日志和C:\windows\sqlstp.log 了解更多信息

    重装sql经常遇到2个问题 1,以前的某个程序安装已在安装计算机上创建挂起的文件操作.运行安装程序之前必须重新启动计算机. 删除C:\Program Files\Microsoft SQL Serve ...

  7. webdriver+expected_conditions二次封装

    结合这两种方法对代码做二次封装,可以提升脚本性能 例: #coding:utf-8 #封装元素方法from selenium import webdriverfrom selenium.webdriv ...

  8. c# 通过.net自带的chart控件绘制饼图pie chart

    c# 通过.net自带的chart控件绘制饼图pie chart   需要实现的目标是: 1.将数据绑定到pie的后台数据中,自动生成饼图. 2.生成的饼图有详细文字的说明. 具体的实现步骤: > ...

  9. Ubuntu 14.04服务器安装及软件配置

    1.安装操作系统,配置root账号,通过sudo设置root的密码 如果使用ubuntu server 14.04,开启root需额外配置 1.开启root远程登录权限 sudo vi /etc/ss ...

  10. 关于Android不能启动的问题

    关于Android不能启动的问题 untracked pid exited[日期:2013-03-26] 来源:Linux社区  作者:Linux [字体:大 中 小]   1.ok6410nandf ...