题面

传送门

题解

坑啊……我好像把\(Splay\)的东西全忘光了……

\(ETT\)(\(Euler\ Tour\ Tree\))是一种可以资瓷比\(LCT\)更多功能的数据结构,然而不管是功能还是复杂度都远远比不上\(TopTree\)和\(LCT\)(然而我似乎连\(TopTree\)都不会……)

然而一般情况下我们需要用到的只有伪\(ETT\),用人话说就是用\(Splay\)维护欧拉序,进栈的时候值为\(+v\),出栈的时候值为\(-v\),那么\(1\)到\(u\)的路径上的所有数之和就是\(dfs\)序上\(ls[1]\)到\(ls[u]\)的所有数之和了(虽然看别的大佬的博客说这东西资瓷查询任意两点间路径和……然而咱并不明白该怎么搞……如果有知道的可以在下面告诉咱一声么qwq)

换根操作的话,就相当于提出一个区间放到另一个地方,\(Splay\)一下就好了

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=E[i].v;i;i=E[i].nx,v=E[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
inline char getop(){R char ch;while((ch=getc())>'Z'||ch<'A');return ch;}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=2e5+5;
struct eg{int v,nx;}E[N];int head[N],tot;
inline void add(R int u,R int v){E[++tot]={v,head[u]},head[u]=tot;}
struct node;typedef node* ptr;
struct node{
ptr fa,lc,rc;int sz,ty;ll sum,t,v;
inline node();
inline void init(R int x,R int s){sz=ty=s,v=sum=x;}
inline void ppd(R ll x){sum+=x*sz,v+=x*ty,t+=x;}
inline void pd(){if(t)lc->ppd(t),rc->ppd(t),t=0;}
inline ptr upd(){sum=lc->sum+rc->sum+v,sz=lc->sz+rc->sz+ty;return this;}
}e[N],*rt;
inline node::node(){lc=rc=fa=e;}
void push(ptr rt,ptr p){if(p!=rt)push(rt,p->fa);p->pd();}
void rotate(ptr &rt,ptr p){
ptr s=p->fa,t=s->fa;
if(s!=rt)(t->lc==s?t->lc:t->rc)=p;else rt=p;
p->fa=t,s->fa=p;
if(s->lc==p)s->lc=p->rc,p->rc->fa=s,p->rc=s->upd();
else s->rc=p->lc,p->lc->fa=s,p->lc=s->upd();
}
ptr splay(ptr &rt,ptr p){
push(rt,p);
while(p!=rt){
if(p->fa!=rt)rotate(rt,p->fa->lc==p^p->fa->fa->lc==p->fa?p:p->fa);
rotate(rt,p);
}
return p->upd();
}
inline ptr lst(ptr p){p=splay(rt,p)->lc;while(p->rc!=e)p=p->rc;return p;}
inline ptr nxt(ptr p){p=splay(rt,p)->rc;while(p->lc!=e)p=p->lc;return p;}
inline ptr split(ptr s,ptr t){s=lst(s),t=nxt(t),splay(rt,s);return splay(s->rc,t);}
int a[N],val[N],ls[N],rs[N],tim;
void dfs(int u){
ls[u]=++tim,val[tim]=u;
go(u)dfs(v);
rs[u]=++tim,val[tim]=-u;
}
void build(ptr &p,int l,int r,ptr fa){
int mid=(l+r)>>1;p=e+mid,p->fa=fa;
val[mid]>0?p->init(a[val[mid]],1):p->init(-a[-val[mid]],-1);
if(l<mid)build(p->lc,l,mid-1,p);
if(mid<r)build(p->rc,mid+1,r,p);
p->upd();
}
inline ll get(R int x){return split(e+ls[1],e+ls[x])->lc->sum;}
void move(int x,int y){
ptr s=split(e+ls[x],e+rs[x]),t=s->lc;
s->lc=t->fa=e,s->upd(),s->fa->upd();
splay(rt,e+ls[y]),s=splay(rt->rc,nxt(rt));
s->lc=t,t->fa=s,s->upd(),s->fa->upd();
}
void tag(int x,int y){split(e+ls[x],e+rs[x])->lc->ppd(y);}
int n,m;
int main(){
// freopen("testdata.in","r",stdin);
n=read();
for(R int i=2,x;i<=n;++i)x=read(),add(x,i);
fp(i,1,n)a[i]=read();
tim=1,dfs(1),build(rt,1,tim+1,e);
m=read();
char op;int x,y;
while(m--){
op=getop(),x=read();
switch(op){
case 'Q':print(get(x));break;
case 'C':y=read(),move(x,y);break;
case 'F':y=read(),tag(x,y);break;
}
}
return Ot(),0;
}

BZOJ3786: 星系探索(伪ETT)的更多相关文章

  1. [BZOJ3786]星系探索(伪ETT)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1638  Solved: 506[Submit][Status][Discuss ...

  2. BZOJ 3786: 星系探索 [伪ETT]

    传送门 数据,标程 题意: 一颗有根树,支持询问点到根路径权值和,子树加,换父亲 欧拉序列怎么求路径权值和? 一个点的权值只会给自己的子树中的点贡献,入栈权值正出栈权值负,求前缀和就行了! 和上题一样 ...

  3. [BZOJ3786]星系探索

    [BZOJ3786]星系探索 试题描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个 ...

  4. BZOJ3786 星系探索 【Splay维护dfs序】*

    BZOJ3786 星系探索 Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均 ...

  5. [BZOJ3786] 星系探索(括号序列+Splay)

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 2191  Solved: 644[Submit][Status][Discuss ...

  6. bzoj3786星系探索 splay

    3786: 星系探索 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1314  Solved: 425[Submit][Status][Discuss ...

  7. BZOJ3786星系探索——非旋转treap(平衡树动态维护dfs序)

    题目描述 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球没有依赖星球. ...

  8. BZOJ3786:星系探索(Splay,括号序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  9. bzoj3786星系探索(splay维护dfs序)

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

随机推荐

  1. VMware 克隆网卡无法启动

    问题描述: 最近学习 hadoop,环境准备搭建在虚拟机之上,装好一台虚拟机克隆完成后,网卡无法启动. 多年前,初学 Linux 的时候,就遇到过这个问题,记录的笔记找不到了,简单记录一下. shel ...

  2. eclipse中debug改变变量的值

    step1:debug断点到变量的下一行,在debug试图的右上角variables中看到该变量的值: step2:鼠标右键点击str出现下图,选择Change Value... step3:点击Ch ...

  3. JAVA程序中使用正则表达式

    import java.util.regex.Matcher;import java.util.regex.Pattern; /** * @author Administrator 测试正则表达式 * ...

  4. 高分辨率下firefox字体和界面自动放大的问题

    电脑是高分屏的情况下,如果我们将DPI调成100%,屏幕字体太小,所以我们经常将DPI设置成125%或者其它,这样屏幕看起来会舒服些.但随之而来的是火狐浏览器的字体界面也会放大, 这也会直接导致我们在 ...

  5. ORA-01157:无法标识/锁定数据文件,ORA-01110:数据文件。。。

  6. Cocoa Touch(三):图形界面UIKit、Core Animation、Core Graphics

    UIKit 视图树模型 1.视图树模型 计算机图形实际上是一个视图树模型,每个视图都有一个本地坐标系.每个本地坐标系的组成部分是:原点在父坐标系中的位置,每个基在父坐标系中的位置,由此就可以根据向量的 ...

  7. animate.css动画种类

    animate.css 一个非常好用的css动画库 Github地址 包括了一下多种动画 1. bounce 弹跳 2. flash 闪烁 3. pulse 放大,缩小 4. rubberBand 放 ...

  8. 洛谷 P3660 [USACO17FEB]Why Did the Cow Cross the Road III G(树状数组)

    题目背景 给定长度为2N的序列,1~N各处现过2次,i第一次出现位置记为ai,第二次记为bi,求满足ai<aj<bi<bj的对数 题目描述 The layout of Farmer ...

  9. python之selenium调用js(execute_script)

    转载: http://www.cnblogs.com/fnng/p/3230768.html 本节重点: 调用js方法 execute_script(script, *args) 在当前窗口/框架 同 ...

  10. [Java] Java API文档下载方法

    Java API文档下载方法:http://jingyan.baidu.com/article/a3aad71ac9e48fb1fb009692.html Oracle : http://www.or ...