2333: [SCOI2011]棘手的操作[离线线段树]
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
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
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]棘手的操作[离线线段树]的更多相关文章
- BZOJ 2333 棘手的操作(离线+线段树+带权并查集)
这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...
- 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: 1979 Solved: 772[Submit][Stat ...
- BZOJ 2333: [SCOI2011]棘手的操作 可并堆 左偏树 set
https://www.lydsy.com/JudgeOnline/problem.php?id=2333 需要两个结构分别维护每个连通块的最大值和所有连通块最大值中的最大值,可以用两个可并堆实现,也 ...
- 【bzoj2333 & luoguP3273】棘手的操作(线段树合并)
题目传送门:bzoj2333 luoguP3273 这操作还真“棘手”..听说这题是可并堆题?然而我不会可并堆.于是我就写了线段数合并,然后调了一晚上,数据结构毁一生!!!QAQ…… 其实这题也可以把 ...
- P3273-[SCOI2011]棘手的操作【线段树,并查集】
正题 题目链接:https://www.luogu.com.cn/problem/P3273 题目大意 \(n\)个点有权值,要求支持操作 连接两个点 单点加权 联通块加权 全图加权 单点询问 联通块 ...
- 洛谷.3273.[SCOI2011]棘手的操作(左偏树)
题目链接 还是80分,不是很懂. /* 七个操作(用左偏树)(t2表示第二棵子树): 1.合并:直接合并(需要将一个t2中原有的根节点删掉) 2.单点加:把这个点从它的堆里删了,加了再插入回去(有负数 ...
- 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]
题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...
- BZOJ 2333: [SCOI2011]棘手的操作
题目描述 真的是个很棘手的操作.. 注意每删除一个点,就需要clear一次. #include<complex> #include<cstdio> using namespac ...
随机推荐
- 算法-Java组合
code: import org.assertj.core.util.Lists; import java.util.ArrayList; import java.util.Collections; ...
- vue、vuex、iview、vue-router报错集锦与爬坑记录
1.vue报错: 没安装 less-loader css-loader style-loader 可能的很大原因:没安装less 2.vuex报错:Computed property &qu ...
- Vue.js 2.0 学习重点记录
Vue.js兼容性 Vue.js.js 不支持 IE8 及其以下版本,因为 Vue.js.js 使用了 IE8 不能模拟的 ECMAScript 5 特性. Vue.js.js 支持所有兼容 EC ...
- 深入理解Java虚拟机(一)
一.运行时数据区域 1.程序计数器: 当前线程执行字节码的行号指示器(通过改变计数器的值来选择下条需要执行的字节码指令) 每个线程有独立的程序计数器(线程私有,为了切换线程时能恢复到挣钱的执行位置 ...
- Webkit内核探究【2】——Webkit CSS实现
注:[转载请注明文章来源.保持原样] 出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660364.html 作者:李嘉昱 CSS在Webkit中 ...
- highcharts系列之xAxis
xAxis定义的是x坐标轴的配置选项.默认情况下,x轴指的是水平轴,特殊指定的时候也可以作为垂直的轴使用,在多坐标系中,xAxis是有多个配置好了的轴object的数组. 下面来看一下,xAxis常用 ...
- Android开发学习笔记-实现联网检测程序版本
package com.frank.mobilesafe; import java.io.InputStream; import java.net.HttpURLConnection; import ...
- CentOS 7 mini安装后安装图形界面及远程设置
安装图形界面 yum group install "GNOME Desktop" "Graphical Administration Tools" 安装 xrd ...
- Java实现高效的枚举元素集合
Set是Java集合类的重要组成部分,它用来存储不能重复的对象.枚举类型也要求其枚举元素各不相同.看起来枚举类型和集合是很相似的.然而枚举类型中的元素不能随意的增加.删除,作为集合而言,枚举类型非常不 ...
- openvpn记住用户名和密码,自动连接
1, 打开openvpn安装目录 2, 在config目录中, 找到VPN服务器的配置文件, 我的是config.ovpn,将 auth-user-pass (若已经存在)改为 auth-user-p ...