洛谷P3273 [SCOI2011]棘手的操作
题目描述
有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作:U x y: 加一条边,连接第x个节点和第y个节点A1 x v: 将第x个节点的权值增加vA2 x v: 将第x个节点所在的连通块的所有节点的权值都增加vA3 v: 将所有节点的权值都增加vF1 x: 输出第x个节点当前的权值F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值F3: 输出所有节点中,权值最大的节点的权值
输入输出格式
输入格式:
输入的第一行是一个整数N,代表节点个数。接下来一行输入N个整数,a[1], a[2], ..., a[N],代表N个节点的初始权值。再下一行输入一个整数Q,代表接下来的操作数。最后输入Q行,每行的格式如题目描述所示。
输出格式:
对于操作F1, F2, F3,输出对应的结果,每个结果占一行。
输入输出样例
说明
对于30%的数据,保证 N<=100,Q<=10000
对于80%的数据,保证 N<=100000,Q<=100000
对于100%的数据,保证 N<=300000,Q<=300000
对于所有的数据,保证输入合法,并且 -1000<=v, a[1], a[2], ..., a[N]<=1000
开两个可并堆堆
分别维护联通快最大值和所有的最大值
U x y: 加一条边,连接第x个节点和第y个节点
直接合并
A1 x v: 将第x个节点的权值增加v
先删掉,再加上原来的权值加v
A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v
跟线段树一样打个标记
A3 v: 将所有节点的权值都增加v
直接用一个变量记录
F1 x: 输出第x个节点当前的权值
直接输出
F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值
找到父亲,输出
F3: 输出所有节点中,权值最大的节点的权值
输出维护最大值的那个堆的根节点
效率暂时rank1

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int MAXN=;
#define ls T[x].ch[0]
#define rs T[x].ch[1]
inline int read()
{
int a;
cin>>a;
return a;
}
int root,N,All;
struct Priority
{
struct node
{
int fa,dis,val,ch[],mark;
}T[MAXN];
void Clear(int x){ls=rs=;T[x].fa=;}
void Pushdown(int x)
{
if(ls) T[ls].val+=T[x].mark,T[ls].mark+=T[x].mark;
if(rs) T[rs].val+=T[x].mark,T[rs].mark+=T[x].mark;
T[x].mark=;
}
int Merge(int x,int y)
{
if(!x||!y) return x+y;
if( T[x].val < T[y].val) swap(x,y);
Pushdown(x);
rs=Merge(rs,y);
T[rs].fa=x;
if(T[rs].dis>T[ls].dis) swap(ls,rs);
T[x].dis=T[rs].dis+;
return x;
}
int Delet(int x)
{
Pushdown(x);
int q=T[x].fa,p=Merge(ls,rs);
T[p].fa=q;
T[q].ch[ T[q].ch[] == x] = p;
while(q)
{
if(T[ T[q].ch[] ].dis < T[ T[q].ch[] ].dis) swap( T[q].ch[] , T[q].ch[] );
if(T[ T[q].ch[] ].dis+ == T[q].dis) return root;
T[q].dis=T[ T[q].ch[] ].dis+;
p=q;q=T[q].fa;
}
return p;
}
int Find(int x)
{
while(T[x].fa) x=T[x].fa;
return x;
}
int Sum(int x)
{
int ans=;
while(x=T[x].fa) ans+=T[x].mark;
return ans;
}
int AddPoint(int x,int v)
{
int fx=Find(x);
if(fx==x)
{
if(ls+rs==)
{T[x].val+=v;return x;}
else
if(ls) fx=ls;
else fx=rs;
}
Delet(x);
T[x].val+=v+Sum(x);
Clear(x);
return Merge(Find(fx),x);
}
int Build()
{
queue<int>q;
for(int i=;i<=N;i++)
q.push(i);
while(q.size()>)
{
int x=q.front();q.pop();
int y=q.front();q.pop();
int z=Merge(x,y);
q.push(z);
}
return q.front();
}
};
Priority h1,h2;
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
freopen("b.out","w",stdout);
#else
#endif
char opt[];
N=read();
h1.T[].dis=h2.T[].dis=-;
for(int i=;i<=N;i++)
h2.T[i].val=h1.T[i].val=read();
root=h2.Build();
int M=read();
while(M--)
{
scanf("%s",opt+);
if(opt[]=='U')
{
int x=read(),y=read();
int fx=h1.Find(x),fy=h1.Find(y);
if(fx!=fy)
{
int tmp=h1.Merge(fx,fy);
if(tmp==fx) root=h2.Delet(fy);
else root=h2.Delet(fx);//优化,根据大根堆的性质,以后的就没有用了
}
}
else if(opt[]=='A')
{
if(opt[]=='')
{
int x=read(),v=read();
root=h2.Delet(h1.Find(x));
int y=h1.AddPoint(x,v);
h2.T[y].val=h1.T[y].val;
h2.Clear(y);
root=h2.Merge(root,y);
}
else if(opt[]=='')
{
int x=read(),v=read();
int fx=h1.Find(x);
root=h2.Delet(fx);
h1.T[fx].val+=v;
h1.T[fx].mark+=v;
h2.T[fx].val=h1.T[fx].val;
h2.Clear(fx);
root=h2.Merge(root,fx);
}
else if(opt[]=='')
{
int v=read();
All+=v;
} }
else if(opt[]=='F')
{
if(opt[]=='')
{
int x=read();
printf("%d\n",h1.T[x].val+h1.Sum(x)+All);
}
else if(opt[]=='')
{
int x=read();
printf("%d\n",h1.T[h1.Find(x)].val+All);
}
else if(opt[]=='')
printf("%d\n",h2.T[root].val+All);
}
}
}
洛谷P3273 [SCOI2011]棘手的操作的更多相关文章
- 洛谷P3273 [SCOI2011] 棘手的操作 [左偏树]
题目传送门 棘手的操作 题目描述 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边,连接第x个节点和第y个节点 A1 ...
- bzoj2333[SCOI2011]棘手的操作 洛谷P3273 [SCOI2011]棘手的操作
2333? 先记一下吧,这题现在全部都是照着题解做的,因为怎么改都改不出来,只好对着题解改,以后还要再做过 以后再也不用指针了!太恶心了!空指针可不止直接特判那么简单啊,竟然还要因为空指针写奇怪的分类 ...
- 洛谷.3273.[SCOI2011]棘手的操作(左偏树)
题目链接 还是80分,不是很懂. /* 七个操作(用左偏树)(t2表示第二棵子树): 1.合并:直接合并(需要将一个t2中原有的根节点删掉) 2.单点加:把这个点从它的堆里删了,加了再插入回去(有负数 ...
- P3273 [SCOI2011]棘手的操作
吐槽 上午风浔凌julao问我的神题 操作又多又毒瘤又棘手... 然后bzoj题号正好是2333,2333333333 思路 貌似只有我是这么写的 线段树合并, 每个线段树存每个连通块的信息,维护点的 ...
- Luogu P3273 [SCOI2011]棘手的操作(左偏树)
什么恶心东西啊,又水又烦 两个可并堆维护即可 #include <cstdio> #include <iostream> #include <cstring> #i ...
- 【bzoj2333】 [SCOI2011]棘手的操作 可并堆+lazy标记
2016-05-31 21:45:41 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 (学习了黄学长的代码 有如下操作: U x y ...
- 【BZOJ 2333 】[SCOI2011]棘手的操作(离线+线段树)
2333: [SCOI2011]棘手的操作 Description 有N个节点,标号从1到N,这N个节点一开始相互不连通.第i个节点的初始权值为a[i],接下来有如下一些操作: U x y: 加一条边 ...
- 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 ...
随机推荐
- Android Studio的Signature Versions选择,分别是什么意思
转自原文 Android Studio的Signature Versions选择,分别是什么意思 打包一个文件的签名版本, 选V1打包出来的app是jar的(一般这种就是当做第三方导入项目来用的), ...
- ArcGIS api for javascript——地理处理任务-瓶中信
描述 如果在海洋中丢下一个瓶子,本例使用颗粒追踪模型显示指定的天数后瓶子在的地方.首先,输入一个追踪瓶子的天数.然后单击按钮并在海洋里的任意地方画一个点来开始模型.几秒以后将看到一条线出现描述瓶子将去 ...
- Android——4.2 - 3G移植之路之 APN (五)
APN,这东西对于刚接触的人来说并非那么好理解.对于3G移植上网不可缺少,这里记录一下. 撰写不易,转载请注明出处:http://blog.csdn.net/jscese/article/detail ...
- Oracle数据库IP访问限制(IP白名单黑名单)
1.编辑sqlnet.ora 内容为: #允许访问的IP(白名单) TCP.INVITED_NODES=(127.0.0.1,192.168.56.109,ip2,ip3,..,..本地IP..)若使 ...
- 学习TF:《TensorFlow技术解析与实战》PDF+代码
TensorFlow 是谷歌公司开发的深度学习框架,也是目前深度学习的主流框架之一.<TensorFlow技术解析与实战>从深度学习的基础讲起,深入TensorFlow框架原理.模型构建. ...
- 【RHEL7/CentOS7服务控制之systemctl命令】
Systemd对于Linux来说,就是一个init程序,可以作为sysVinit和Upstat的替代. RHEL7监控和控制Systemd的主要命令是systemctl,该命令可查看系统状态和管理系统 ...
- fgrep---指定的输入文件中的匹配模式的行
fgrep命令是用来搜索 file 参数指定的输入文件(缺省为标准输入)中的匹配模式的行.fgrep 命令特别搜索 Pattern 参数,它们是固定的字符串.如果在 File 参数中指定一个以上的文件 ...
- Annotation中Result的params属性
这个属性只有在重定向时有用,而转发时不会设置参数. 如: @Results({ @Result(name="success", location="page", ...
- java.lang.IllegalArgumentException: The observer is null.终于解决方式
java.lang.IllegalArgumentException: The observer is null.终于解决方式 在使用数据适配的时候的问题: java.lang.IllegalArgu ...
- QCAD Plugin 开发
QCAD Plugin 开发 eryar@163.com Abstract. QCAD是基于GPL协议的开源CAD软件,核心功能基于Qt使用C++开发,界面及其交互使用Javascript脚本进行开发 ...