2333333333333
题号厉害 此题必做。。。
据说是什么什么可并堆(没听说过orz
于是自己yy了一个用splay + 线段树的作法
线段树用来维护全局最大值
splay维护单点最大 连通块最大
作法。略。。
#include <cstdio>
#include <iostream>
using namespace std;
char s[2];
int n,q,u,v,All;
int x[300010],ma[300010],ch[300010][2],fa[300010],lz[300010],st[300010],tp;
int X[1200010],l[1200010],r[1200010];
int father[300010];
int read_int () {
char c = getchar();
int re = 0,f = 1;
for(;c > '9' || c < '0';c = getchar())
if(c == '-') f = -1;
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re * f;
}
int find (int u) {
if(father[u] == u)
return u;
return father[u] = find(father[u]);
}
void build (int L,int R,int M) {
l[M] = L;
r[M] = R;
if(L == R) {
X[M] = x[L];
return;
}
int mid = (L + R) >> 1;
build(L,mid,M << 1);
build(mid + 1,R,M << 1 | 1);
X[M] = max(X[M << 1],X[M << 1 | 1]);
}
void change (int pos,int M,int v) {
if(l[M] == r[M] && l[M] == pos) {
X[M] = v;
return;
}
int mid = (l[M] + r[M]) >> 1;
if(pos > mid)
change(pos,M << 1 | 1,v);
else change(pos,M << 1,v);
X[M] = max(X[M << 1],X[M << 1 | 1]);
}
void pu (int M) {
ma[M] = x[M];
ma[M] = max(ma[M],ma[ch[M][0]]);
ma[M] = max(ma[M],ma[ch[M][1]]);
}
void add (int M,int v) {
x[M] += v;
ma[M] += v;
lz[M] += v;
}
void pd (int M) {
if(lz[M] == 0)
return;
if(ch[M][0])
add(ch[M][0],lz[M]);
if(ch[M][1])
add(ch[M][1],lz[M]);
lz[M] = 0;
}
void rot (int M,int d) {
ch[fa[M]][d ^ 1] = ch[M][d];
if(ch[M][d])
fa[ch[M][d]] = fa[M];
int t = fa[fa[M]];
fa[fa[M]] = M;
ch[M][d] = fa[M];
fa[M] = t;
pu(ch[M][d]);
pu(M);
if(!t)
return;
if(ch[t][0] == ch[M][d])
ch[t][0] = M;
else ch[t][1] = M;
}
void splay (int M) {
st[tp = 1] = M;
int t = M;
while(fa[t]) {
t = fa[t];
st[++tp] = t;
}
while(tp)
pd(st[tp--]);
while(fa[M]) {
if(fa[fa[M]]) {
int d = ch[fa[fa[M]]][0] == fa[M];
if(ch[fa[M]][d] == M) {
rot(M,d ^ 1);
rot(M,d);
}
else {
rot(M,d);
rot(M,d);
}
}
else {
if(ch[fa[M]][0] == M)
rot(M,1);
else rot(M,0);
}
}
}
int main () {
ma[0] = -0x3f3f3f3f;
n = read_int();
for(int i = 1;i <= n;++i) {
ma[i] = x[i] = read_int();
father[i] = i;
}
build(1,n,1);
q = read_int();
for(int i = 1;i <= q;++i) {
scanf("%s",s);
if(s[0] == 'U') {
u = read_int();
v = read_int();
if(find(u) != find(v)) {
change(find(u),1,-0x3f3f3f3f);
father[find(u)] = find(v);
splay(u);
splay(v);
int t = u;
while(ch[t][0])
t = ch[t][0];
splay(t);
fa[v] = t;
ch[t][0] = v;
pu(t);
change(find(v),1,ma[t]);
}
}
else {
if(s[0] == 'A') {
if(s[1] == '3')
All += read_int();
else {
u = read_int();
v = read_int();
if(s[1] == '1') {
splay(u);
x[u] += v;
int t = ma[u];
pu(u);
if(t != ma[u])
change(find(u),1,ma[u]);
}
else {
splay(u);
add(u,v);
change(find(u),1,ma[u]);
}
}
}
else {
if(s[1] == '3')
printf("%d\n",X[1] + All);
else {
u = read_int();
splay(u);
if(s[1] == '1')
printf("%d\n",x[u] + All);
else printf("%d\n",ma[u] + All);
}
}
}
}
}