# [BZOJ3786]星系探索

[BZOJ3786]星系探索

(1)"Q di"表示小C要开始一次实验,收集器的初始位置在星球di.

(2)"C xi yi"表示星球xi的依赖星球变为了星球yi.

(3)"F pi qi"表示星球pi能量激发，常数为qi.

3
1
1
4 5 7
5
Q 2
F 1 3
Q 2
C 2 3
Q 2

9
15
25

n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000.保证操作合法。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

const int BufferSize = 1 << 16;
inline char Getchar() {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
}
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
}

#define maxn 100010
#define maxm 200010
#define LL long long
int n;

int clo, val[maxn], dl[maxn], dr[maxn], ids[maxn<<1], dv[maxn<<1], ds[maxn<<1];
void AddEdge(int a, int b) {
swap(a, b);
return ;
}
void build(int u, int fa) {
dl[u] = ++clo; dv[clo] = val[u]; ds[clo] = 1;
for(int e = head[u]; e; e = next[e]) if(to[e] != fa) build(to[e], u);
dr[u] = ++clo; dv[clo] = -val[u]; ds[clo] = -1;
return ;
}

struct Node {
int sym, sums;
Node() { val = sumv = addv = sym = sums = 0; }
void clear() { val = sumv = addv = sym = sums = 0; return ; }
} nodes[maxn<<1];
int ToT, root, ch[maxn<<1][2], fa[maxn<<1];
void maintain(int u) {
nodes[0].clear();
Node &o = nodes[u], &l = nodes[ch[u][0]], &r = nodes[ch[u][1]];
o.sums = l.sums + o.sym + r.sums;
o.sumv = l.addv * l.sums + l.sumv + o.val + r.addv * r.sums + r.sumv;
return ;
}
void builds(int& u, int pa, int L, int R) {
if(L > R){ u = 0; return ; }
int M = L + R >> 1;
Node& o = nodes[u = ++ToT];
o.sym = o.sums = ds[M];
o.val = o.sumv = dv[M]; o.addv = 0;
ids[M] = u; fa[u] = pa;
builds(ch[u][0], u, L, M - 1); builds(ch[u][1], u, M + 1, R);
maintain(u);
return ;
}
void pushdown(int u) {
Node &o = nodes[u], &l = nodes[ch[u][0]], &r = nodes[ch[u][1]];
//		printf("%lld ", o.sumv);
}
nodes[0].clear();
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(ch[y][1] == u) swap(l, r);
if(z) ch[z][ch[z][1]==y] = u;
fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
int St[maxn], top;
void splay(int u) {
int t = u;
while(fa[t]) St[++top] = t, t = fa[t];
St[++top] = t;
while(top) pushdown(St[top--]);
while(fa[u]) {
int y = fa[u], z = fa[y];
if(!z) rotate(u);
else {
if((ch[z][0] == y) ^ (ch[y][0] == u)) rotate(u);
else rotate(y);
rotate(u);
}
}
return ;
}
int splitl(int u) {
splay(u);
int ret = ch[u][0];
Node &o = nodes[u], &l = nodes[ch[u][0]];
nodes[0].clear();
o.sumv -= (l.sumv + l.addv * l.sums);
fa[ret] = 0; ch[u][0] = 0;
return ret;
}
int splitr(int u) {
splay(u);
int ret = ch[u][1];
Node &o = nodes[u], &r = nodes[ch[u][1]];
nodes[0].clear();
o.sumv -= (r.sumv + r.addv * r.sums);
fa[ret] = 0; ch[u][1] = 0;
return ret;
}
void update(int u, int v) {
splay(u);
return ;
}
void merge(int a, int b) {
if(!a || !b) return ;
while(ch[a][1]) a = ch[a][1];
while(ch[b][0]) b = ch[b][0];
splay(a); splay(b);
Node &o = nodes[b], &l = nodes[a];
o.sumv += (l.sumv + l.addv * l.sums);
fa[a] = b; ch[b][0] = a;
return ;
}

int main() {
for(int i = 1; i <= n; i++) val[i] = read();

build(1, 0);
builds(root, 0, 1, n << 1);
while(q--) {
char tp = Getchar();
while(!isalpha(tp)) tp = Getchar();
if(tp == 'Q') {
splay(ids[x]);
Node& o = nodes[ids[x]], &r = nodes[ch[ids[x]][1]];
LL ans = o.sumv + o.addv * o.sums - r.sumv - r.addv * r.sums;
printf("%lld\n", ans);
}
if(tp == 'F') {
int x = read(), v = read(), xl = dl[x], xr = dr[x], lt = 0, rt = 0;
lt = splitl(ids[xl]);
rt = splitr(ids[xr]);
update(ids[xl], v);
merge(lt, ids[xl]);
merge(ids[xr], rt);
}
if(tp == 'C') {
int x = read(), fax = read(), xl = dl[x], xr = dr[x], lt, rt;
lt = splitl(ids[xl]);
rt = splitr(ids[xr]);
merge(lt, rt);
rt = splitr(ids[dl[fax]]);
lt = ids[dl[fax]];
merge(lt, ids[xl]);
merge(ids[xr], rt);
}
}

return 0;
}


posted @ 2016-08-05 15:33  xjr01  阅读(207)  评论(0编辑  收藏  举报