深圳专业网站建设技术,西安家电商城网站建设,高端网站建设优化,国外网站建设推广BZOJ#3786. 星系探索
Solution
子树加#xff0c;换fatherfatherfather#xff08;保证还是树#xff09;#xff0c;询问到根路径和。 树上路径求和不好动态维护#xff0c;于是转化到序列上#xff0c;维护一个括号序#xff0c;dfndfndfn处贡献为www#xff0c;fn…BZOJ#3786. 星系探索
Solution
子树加换fatherfatherfather保证还是树询问到根路径和。 树上路径求和不好动态维护于是转化到序列上维护一个括号序dfndfndfn处贡献为wwwfnsfnsfns处贡献为−w-w−w一段路径(x,y)(x,y)(x,y)的和相当于序列上dfnxdfn_xdfnx到dfnydfn_ydfny的贡献和。
于是子树加相当于区间加交换子树相当于在括号序上取出一个区间插入到其他地方去。 这个可以直接用平衡树维护这里用的是fhq−treapfhq-treapfhq−treap。
我们在fhq−treapfhq-treapfhq−treap中节点的下标对应的是原树的括号序编号即dfnxdfn_xdfnx在treaptreaptreap上对应dfnxdfn_xdfnx号节点在splitsplitsplit时当前的括号序为中序遍历treaptreaptreap后得到的节点编号序列。需要求出节点在treaptreaptreap上的rankrankrank然后再按rankrankrank分成两棵子树。
剩下的就是treaptreaptreap的区间标记维护区间和了注意dfnxΔdfn_x\DeltadfnxΔ则fnsx−Δfns_x-\Deltafnsx−Δ因此我们的区间和要带符号维护。
时间复杂度O(nlgn)O(nlgn)O(nlgn)。
Code
#include vector
#include list
#include map
#include set
#include deque
#include queue
#include stack
#include bitset
#include algorithm
#include functional
#include numeric
#include utility
#include sstream
#include iostream
#include iomanip
#include cstdio
#include cmath
#include cstdlib
#include cctype
#include string
#include cstring
#include ctime
#include cassert
#include string.h
//#include unordered_set
//#include unordered_map
//#include bits/stdc.h#define MP(A,B) make_pair(A,B)
#define PB(A) push_back(A)
#define SIZE(A) ((int)A.size())
#define LEN(A) ((int)A.length())
#define FOR(i,a,b) for(int i(a);i(b);i)
#define fi first
#define se secondusing namespace std;templatetypename Tinline bool upmin(T x,T y) { return yx?xy,1:0; }
templatetypename Tinline bool upmax(T x,T y) { return xy?xy,1:0; }typedef long long ll;
typedef unsigned long long ull;
typedef long double lod;
typedef pairint,int PR;
typedef vectorint VI;const lod eps1e-11;
const lod piacos(-1);
const int oo130;
const ll loo1ll62;
const int mods998244353;
const int MAXN600005;
const int INF0x3f3f3f3f;//1061109567
/*--------------------------------------------------------------------*/
inline int read()
{int f1,x0; char cgetchar();while (c0||c9) { if (c-) f-1; cgetchar(); }while (c0c9) { x(x3)(x1)(c^48); cgetchar(); }return x*f;
}
struct fhq_treap
{ll a[MAXN],sum[MAXN],tag[MAXN];int b[MAXN],sz[MAXN],p[MAXN],num[MAXN],fa[MAXN],ch[MAXN][2],rt;void up(int x) { sz[x]sz[ch[x][0]]sz[ch[x][1]]1;num[x]num[ch[x][0]]num[ch[x][1]]p[x];sum[x]sum[ch[x][0]]sum[ch[x][1]]a[x]; if (ch[x][0]) fa[ch[x][0]]x;if (ch[x][1]) fa[ch[x][1]]x;}void puttag(int x,ll y) { if (!x) return; tag[x]y,a[x]y*p[x],sum[x]y*num[x]; }void down(int x) { if (!x||tag[x]0) return;puttag(ch[x][0],tag[x]),puttag(ch[x][1],tag[x]),tag[x]0;}int nwnode(int id,int opt,int x) { p[id]num[id]opt;a[id]sum[id]opt*x;b[id]rand(),sz[id]1; return id; }void split(int nw,int k,int x,int y){if (!nw) xy0;else{down(nw);if (ksz[ch[nw][0]]) ynw,split(ch[nw][0],k,x,ch[nw][0]);else xnw,split(ch[nw][1],k-sz[ch[nw][0]]-1,ch[nw][1],y);up(nw);}}int merge(int x,int y){if (!x||!y) return x|y;down(x),down(y);if (b[x]b[y]) return ch[x][1]merge(ch[x][1],y),up(x),x;else return ch[y][0]merge(x,ch[y][0]),up(y),y;}int rank(int x){int rksz[ch[x][0]]1;while (fa[x]) {if (xch[fa[x]][1]) rksz[ch[fa[x]][0]]1;xfa[x];}return rk;}ll Query(int x){int A,B;split(rt,rank(x),A,B);ll anssum[A];rtmerge(A,B);return ans;}void Swap(int l,int r,int x){int A,B,C,D;lrank(l),rrank(r),xrank(x);if (xl-1) //1...x...l...r...n{split(rt,r,A,D);split(A,l-1,A,B);split(A,x,A,C);rtmerge(merge(merge(A,B),C),D);}else{split(rt,x,A,D); //1...l...r...x...nsplit(A,r,A,B);split(A,l-1,A,C);rtmerge(merge(merge(A,B),C),D);}}void Update(int l,int r,int y){int A,B,C;lrank(l),rrank(r);split(rt,r,A,C);split(A,l-1,A,B);puttag(B,y);rtmerge(merge(A,B),C);}
} T;
vectorint e[MAXN];
int dfn[MAXN],fns[MAXN],w[MAXN],DFN0;
void dfs(int x,int father)
{dfn[x]DFN;T.rtT.merge(T.rt,T.nwnode(DFN,1,w[x]));for (auto v:e[x]) if (v!father) dfs(v,x);fns[x]DFN;T.rtT.merge(T.rt,T.nwnode(DFN,-1,w[x]));
}
signed main()
{srand(time(0));int nread();for (int i2;in;i) e[read()].PB(i);for (int i1;in;i) w[i]read();dfs(1,0);int Caseread();while (Case--){int x,y; char c; scanf(%c,c);if (cQ) xread(),printf(%lld\n,T.Query(dfn[x]));else if (cC) xread(),yread(),T.Swap(dfn[x],fns[x],dfn[y]);else xread(),yread(),T.Update(dfn[x],fns[x],y);}return 0;
}