星系探索

题解

一道ETT板子题
笔者最开始用FHQ_Treap打的ETT,忘记可以沿 f a fa fa算出它的欧拉序,一直没调出来,于是就改用splay了。

ETT的模板。其实我觉得叫它平衡树板子就可以了
我们可以先通过欧拉序建出一颗平衡树来,令 i n x in_{x} inx​为点 x x x的入欧拉序, o u t x out_{x} outx​为点 x x x的出欧拉序。
容易发现, i n r o o t in_{root} inroot​到 i n v in_{v} inv​的区间中删去既有出又有入的点,得到的就是从根到点 v v v的入点的路径。
于是,第一个操作求这条路径的和我们可以转化为求这个区间之和。将点 o u t x out_{x} outx​的权值赋值为点 i n x in_{x} inx​的相反数,这样统计得到的区间的和可以将没有经过的点消去,得到答案。
我们又知道,从 i n x in_{x} inx​到 o u t x out_{x} outx​的区间是点 x x x的子树,所以只需要将这个区间拆下来,接到其后面就可以完成操作二了。
操作三也就是平衡树的常规操作,打个懒标记就能解决。

源码

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define MAXN 200005
typedef long long LL;
const LL INF=0x7f7f7f7f;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
template<typename _T>
void read(_T &x){_T f=1;x=0;char s=getchar();while('0'>s||'9'<s){if(s=='-')f=-1;s=getchar();}while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}x*=f;
}
struct edge{int to,nxt;}e[MAXN];
int head[MAXN],tot,a[MAXN],n,m;
void addEdge(int u,int v){e[++tot]=(edge){v,head[u]};head[u]=tot;}
class Splay{private:int siz[MAXN],ch[MAXN][2],val[MAXN];int lzy[MAXN],fa[MAXN],cnt[MAXN];int sta[MAXN],stak,root;LL sum[MAXN]; void pushup(int rt){siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+cnt[rt];sum[rt]=sum[ch[rt][0]]+sum[ch[rt][1]]+1ll*cnt[rt]*val[rt];}void work(int rt,int w){if(!rt)return ;val[rt]+=w;lzy[rt]+=w;sum[rt]+=1ll*siz[rt]*w;}void pushdown(int rt){if(!lzy[rt])return ;work(ch[rt][0],lzy[rt]);work(ch[rt][1],lzy[rt]);lzy[rt]=0;}void rotate(int x,int &k){//printf("%d %d\n",x,k);int y=fa[x],z=fa[y],l,r;if(ch[y][0]==x)l=0;else l=1;r=l^1;if(y==k)k=x;else{if(ch[z][0]==y)ch[z][0]=x;else ch[z][1]=x;}fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y;pushup(y);pushup(x);}void splay(int x,int &k){//printf("%d %d\n",x,k);sta[++stak]=x;for(int i=x;i^root;i=fa[i])sta[++stak]=fa[i];for(int i=stak;i;i--)pushdown(sta[i]);stak=0;while(x!=k){int y=fa[x],z=fa[y];if(y!=k){int d1=(ch[z][0]==y),d2=(ch[y][0]==x);if(d1^d2)rotate(x,k);else rotate(y,k);}rotate(x,k);}}int findL(int x){while(ch[x][0])x=ch[x][0];return x;}int findR(int x){while(ch[x][1])x=ch[x][1];return x;}public:void insert(int x,int v,int w){if(!root)root=x;else fa[x]=root,ch[root][1]=x;val[x]=v;cnt[x]=w;pushup(x);splay(x,root);}LL query(int x){splay(x,root);return sum[ch[x][0]]+1ll*cnt[x]*val[x];}void link(int x,int y){splay(x,root);int t1=findR(ch[root][0]);splay(x+n+1,root);int t2=findL(ch[root][1]);splay(t1,root);splay(t2,ch[t1][1]);int z=ch[t2][0];fa[z]=ch[t2][0]=0;splay(y,root);int t3=findL(ch[y][1]);splay(t3,ch[y][1]);fa[z]=t3;ch[t3][0]=z;}void modify(int x,int w){splay(x,root);int t1=findR(ch[root][0]);splay(x+n+1,root);int t2=findL(ch[root][1]);splay(t1,root);splay(t2,ch[t1][1]);work(ch[t2][0],w);}void build(int u){insert(u+1,a[u],1);for(int i=head[u];i;i=e[i].nxt)build(e[i].to);insert(u+n+2,a[u],-1);}
}T;
signed main(){read(n);for(int i=2,f;i<=n;i++)read(f),addEdge(f,i);for(int i=1;i<=n;i++)read(a[i]);T.insert(1,0,0);T.build(1);T.insert(2*n+3,0,0);read(m);char opt[20]={};while(m--){scanf("%s",opt);int x,y;if(opt[0]=='Q')read(x),printf("%lld\n",T.query(x+1));if(opt[0]=='C')read(x),read(y),T.link(x+1,y+1);if(opt[0]=='F')read(x),read(y),T.modify(x+1,y);}return 0;
}

谢谢!!!

[BZOJ3786]星系探索相关推荐

  1. bzoj3786星系探索 splay

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

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

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

  3. bzoj3786: 星系探索

    学到了新姿势,splay维护括号序列(听说是伪ETT(euler-tour-tree 欧拉搜索树)?) 大型工业题 注意点:1:结构改变了以后编号变成不连续的了,要找前驱和后继 2:就算lazy也需要 ...

  4. BZOJ#3786. 星系探索(平衡树,fhq-treap,弱化版ETT)

    BZOJ#3786. 星系探索 Solution 子树加,换fatherfatherfather(保证还是树),询问到根路径和. 树上路径求和不好动态维护,于是转化到序列上,维护一个括号序,dfndf ...

  5. android探索宇宙app,AR研学星系探索app

    AR研学星系探索app是一款为喜欢探索宇宙的用户们提供的关于八大行星学习的软件:通过VR虚拟的形式让用户可以更加直观地了解到我们的地球和我们的浩瀚的宇宙,来启发用户对宇宙的探索和好奇.这款软件会为用户 ...

  6. BZOJ3786 星际探索

    @(BZOJ)[DFS序, Splay] Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其 ...

  7. [BZOJ 3786] 星系探索

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

  8. BZOJ 3786: 星系探索 欧拉游览树

    一个叫 Euler-Tour-Tree 的数据结构,说白了就是用 Splay_Tree 维护欧拉序 #include <cstring> #include <algorithm> ...

  9. bzoj3786 星际探索 splay dfs序

    这道题 首先 因为他求的是当前点到根节点的路径和 我们可以将题目转换为括号序列的写法 将点拆为左括号以及右括号 左括号为正 右括号为负 这样题目就变为了求前缀和了 如果一个点是这个点的子树 那么他的左 ...

最新文章

  1. java父类调用被子类重写的方法
  2. python 列表 元组 字符串
  3. 计算机网络多元化媒体传达,【多媒体技术论文】视觉传达设计多媒体技术的应用(共4007字)...
  4. apache 添加下载文件头
  5. 在新版本caffe里添加新的一层(向旧格式中加)
  6. 并发框架disruptor(高性能内存Queue)
  7. springboot做网站_Github点赞接近100k的SpringBoot学习教程+实战推荐!牛批!
  8. MA5626 MA5821 POE供电版开启POE供电高优先级配置指导
  9. 嵌入式Linux容器技术
  10. UE4 自定义按键事件(踩坑记录)
  11. 计算机类专业学习难度排行,全国33所名校计算机专业考研跨考难度系数排名
  12. C++ 一文解决 数据库ODB 安装/调试/使用的问题
  13. App uni.downloadFile ios问题
  14. mysql表设计实例
  15. linux下freerdp编译,linux下安装freerdp连接windows远程桌面的好软件软件
  16. centos7 linux ffmpeg 改变 修改 视频 帧频 shell 懒人系列-17
  17. orangepi——i2c协议,0led显示
  18. vue3 钉钉扫码登录第三方网站 最新解决方案
  19. Spring-Mybatis整合源码分析
  20. Admin Lite v3.1 - PHP 管理面板 + 用户管理

热门文章

  1. Dapr简单入门(一)
  2. dell t110服务器做系统,企业第一台服务器 戴尔T110 II深度评测
  3. scrollLeft
  4. RFID13.56MHz模拟门禁(相关软件、驱动下载和使用教程已放在参考文献)
  5. 实习医生格蕾第十三季/全集Grey’s Anatomy迅雷下载
  6. Mule封装DB以及Mule Rest接口开发
  7. Java开发必看!拼多多+携程+蚂蚁金服技术面集合
  8. 华为、小米、高盛、凯斯纽荷兰、兰博基尼等公司高管变动
  9. 化学相关计算机知识点,计算机在中学化学教学中的应用
  10. 【JSP】Tomcat安装教程