社区讨论
蒟蒻求大佬帮助
P3273[SCOI2011] 棘手的操作参与者 4已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mi6z6ina
- 此快照首次捕获于
- 2025/11/20 13:12 4 个月前
- 此快照最后确认于
- 2025/11/20 13:12 4 个月前
RT,蒟蒻初学左偏树,样例输出
CPP-20
0
10
思路
CPP维护一个全局标记和每个节点的标记,合并时下传。
A1操作删除节点然后重新插入。
A2操作在根节点打标记,通过并查集实现。
A3操作更新全局标记。
然后更新的时候顺便记录最大值。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
namespace StandardIO {
template<typename T>inline void read (T &x) {
x=0;T f=1;char c=getchar();
for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
x*=f;
}
template<typename T>inline void write (T x) {
if (x<0) putchar('-'),x*=-1;
if (x>=10) write(x/10);
putchar(x%10+'0');
}
}
using namespace StandardIO;
namespace Solve {
const int N=300300;
int n,q;
int a[N],root[N];
int tot,tot_tag,tot_max;
struct node {
int ls,rs,fa;
int val,tag;
int dis;
} heap[N];
void pushdown (int x) {
if (heap[x].tag) {
heap[heap[x].ls].tag+=heap[x].tag;
heap[heap[x].rs].tag+=heap[x].tag;
heap[heap[x].ls].val+=heap[x].tag;
heap[heap[x].rs].val+=heap[x].tag;
heap[x].tag=0;
}
}
int merge (int x,int y) {
if (!x||!y) return x+y;
if (heap[x].val<heap[y].val) swap(x,y);
pushdown(x);
heap[x].rs=merge(heap[x].rs,y);
if (heap[heap[x].ls].dis<heap[heap[x].rs].dis) swap(heap[x].ls,heap[x].rs);
heap[heap[x].ls].fa=x,heap[heap[x].rs].fa=x;
heap[x].dis=heap[heap[x].rs].dis+1;
tot_max=max(tot_max,heap[x].val);
return x;
}
int pop (int x) {
x=merge(heap[x].ls,heap[x].rs);
return x;
}
int newNode (int v) {
heap[++tot].val=v,heap[tot].fa=tot;
heap[tot].ls=heap[tot].rs=heap[tot].dis=heap[tot].tag=0;
tot_max=max(tot_max,heap[tot].val);
return tot;
}
int add (int x,int v) {
int tmp=heap[x].val;
int rest=pop(x);
x=newNode(tmp+v);
x=merge(x,rest);
tot_max=max(tot_max,heap[x].val);
return x;
}
int find (int x) {
while (heap[x].fa!=x) x=heap[x].fa;
return x;
}
void block_add (int x,int v) {
int top=find(x);
heap[top].tag+=v;
}
void all_add (int v) {
tot_tag+=v;
}
int value (int x) {
return heap[x].val;
}
int block_max (int x) {
int top=find(x);
return heap[top].val;
}
int all_max () {
return tot_max+tot_tag;
}
inline void solve () {
read(n);
for (register int i=1; i<=n; ++i) {
read(a[i]);
root[i]=newNode(a[i]);
}
read(q);
while (q--) {
string op;int x,y;
cin>>op;
if (op=="U") {
read(x),read(y);
root[x]=merge(root[x],root[y]);
} else if (op=="A1") {
read(x),read(y);
root[x]=add(root[x],y);
} else if (op=="A2") {
read(x),read(y);
block_add(root[x],y);
} else if (op=="A3") {
read(x);
all_add(x);
} else if (op=="F1") {
read(x);
write(value(root[x])+tot_tag),putchar('\n');
} else if (op=="F2") {
read(x);
write(block_max(root[x])+tot_tag),putchar('\n');
} else {
write(all_max()),putchar('\n');
}
}
}
}
using namespace Solve;
int main () {
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
solve();
}
望大佬赐教。
回复
共 8 条回复,欢迎继续交流。
正在加载回复...