BZOJ3786 星系探索 【Splay维护dfs序】*
BZOJ3786 星系探索
Description
物理学家小C的研究正遇到某个瓶颈。
他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球。主星球没有依赖星球。
我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c.
对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的。并且从星球a出发只能直接到达它的依赖星球b.
每个星球i都有一个能量系数wi.小C想进行若干次实验,第i次实验,他将从飞船上向星球di发射一个初始能量为0的能量收集器,能量收集器会从星球di开始前往主星球,并收集沿途每个星球的部分能量,收集能量的多少等于这个星球的能量系数。
但是星系的构成并不是一成不变的,某些时刻,星系可能由于某些复杂的原因发生变化。
有些时刻,某个星球能量激发,将使得所有依赖于它的星球以及他自己的能量系数均增加一个定值。还有可能在某些时刻,某个星球的依赖星球会发生变化,但变化后依满足依赖关系是无环的。
现在小C已经测定了时刻0时每个星球的能量系数,以及每个星球(除了主星球之外)的依赖星球。接下来的m个时刻,每个时刻都会发生一些事件。其中小C可能会进行若干次实验,对于他的每一次实验,请你告诉他这一次实验能量收集器的最终能量是多少。
Input
第一行一个整数n,表示星系的星球数。
接下来n-1行每行一个整数,分别表示星球2-n的依赖星球编号。
接下来一行n个整数,表示每个星球在时刻0时的初始能量系数wi.
接下来一行一个整数m,表示事件的总数。
事件分为以下三种类型。
(1)”Q di”表示小C要开始一次实验,收集器的初始位置在星球di.
(2)”C xi yi”表示星球xi的依赖星球变为了星球yi.
(3)”F pi qi”表示星球pi能量激发,常数为qi.
Output
对于每一个事件类型为Q的事件,输出一行一个整数,表示此次实验的收集器最终能量。
Sample Input
3
1
1
4 5 7
5
Q 2
F 1 3
Q 2
C 2 3
Q 2
Sample Output
9
15
25
HINT
n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000" role="presentation">1<di,xi<=n,wi,qi<=1000001<di,xi<=n,wi,qi<=100000.保证操作合法。注意wi>=0" role="presentation">wi>=0wi>=0
tips:
罪恶的卡常,本机20s-在BZOJ上却要T,BZOJ的评测机是土豆吗??
强烈建议BZOJ把评测机换一换
反正代码是正确的,卡常之类的就不管了吧
首先可以发现这个结构是一个树形结构,然后操作就是查询一个点到根节点的路径权值和,修改一个节点的父亲,还有把一个子树都加上一个值
一开始想玩LCT,但发现LCT维护子树信息好像很困难?
所以转念一想,想到了dfs序的优美性质,这样就可以把求和转化成前缀和,把修改父亲转化成区间平移,把子区间加上值直接转换成把入栈节点和出栈节点之间的数加上一个值(区间修改?)
然后就Splay了
我是因为听闻非旋Treap常数大才没有写,没想到Splay也卡常啊。。。
这代码过不了啊
#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define LL long long
#define pi pair<int,int>
inline int read(){
int ans=0,w=1;char c=getchar();
while(!isdigit(c)&&c!='-')c=getchar();
if(c=='-')w=-1,c=getchar();
while(isdigit(c))ans=(ans<<1)+(ans<<3)+c-'0',c=getchar();
return ans*w;
}
inline void print(LL x){
if(x<0){putchar('-');x=-x;}
if(x>9)print(x/10);
putchar((x-(x/10)*10)+'0');
}
struct Edge{int v,next;}E[N];
int head[N]={0},tot=0;
int n,q,id[N],dfn=0;
int w[N];
pi st[N];
inline void add(int u,int v){
E[++tot]=(Edge){v,head[u]};
head[u]=tot;
}
inline void dfs(int u,int fa){
id[++dfn]=u;
st[dfn]=(pi){w[u],1};
for(int i=head[u];i;i=E[i].next)
if(E[i].v!=fa)dfs(E[i].v,u);
id[++dfn]=u+n;
st[dfn]=(pi){-w[u],-1};
}
int root,fa[N],son[N][2],cnt=0;
int tag[N],siz[N],num[N],typ[N];
LL sum[N],val[N];
inline void pushup(int t){
sum[t]=sum[son[t][0]]+sum[son[t][1]]+val[t];
siz[t]=siz[son[t][0]]+siz[son[t][1]]+1;
num[t]=num[son[t][0]]+num[son[t][1]]+typ[t];
}
inline void pushnow(int t,LL vl){
tag[t]+=vl;
if(typ[t]>0)val[t]+=vl;
else val[t]-=vl;
sum[t]+=vl*num[t];
}
inline void pushdown(int t){
if(fa[t])pushdown(fa[t]);
if(tag[t]){
pushnow(son[t][0],tag[t]);
pushnow(son[t][1],tag[t]);
tag[t]=0;
}
}
inline bool Son(int t){return son[fa[t]][1]==t;}
inline void rotate(int t){
int f=fa[t],g=fa[f];
bool a=Son(t),b=a^1;
if(g)son[g][Son(f)]=t;fa[t]=g;
son[f][a]=son[t][b];fa[son[f][a]]=f;
son[t][b]=f;fa[f]=t;
pushup(f);pushup(t);
}
inline void splay(int t,int tp){
if(!t)return;
pushdown(t);
while(fa[t]!=tp){
int f=fa[t];
if(fa[f]!=tp){
if(Son(t)^Son(f))rotate(t);
else rotate(f);
}
rotate(t);
}
if(!tp)root=t;
}
inline int build(int l,int r){
if(l>r)return 0;
int mid=(l+r)>>1,t=id[mid];
val[t]=sum[t]=st[mid].first;
num[t]=typ[t]=st[mid].second;
siz[t]=1;tag[t]=0;
if(l==r)return t;
fa[son[t][0]=build(l,mid-1)]=t;
fa[son[t][1]=build(mid+1,r)]=t;
pushup(t);
return t;
}
inline int pre(int pos){
int t=son[pos][0];
while(son[t][1])t=son[t][1];
return t;
}
inline int nxt(int pos){
int t=son[pos][1];
while(son[t][0])t=son[t][0];
return t;
}
inline void modify(int l,int r,LL vl){
int ll=pre(l),rr=nxt(r);
splay(ll,0);
splay(rr,root);
pushnow(son[son[root][1]][0],vl);
}
inline LL query(int pos){
splay(pos,0);
return sum[son[pos][0]]+val[pos];
}
inline void change(int pos,int father){
int lx=pre(pos),rx=nxt(pos+n);
splay(lx,0);
splay(rx,lx);
int t=son[rx][0];
fa[t]=0;son[rx][0]=0;
int lf=nxt(father);
splay(father,0);
splay(lf,father);
son[lf][0]=t;fa[t]=lf;
pushup(lf);
pushup(father);
}
int main(){
n=read();
for(int i=2;i<=n;i++){
int x=read();
add(i,x);add(x,i);
}
for(int i=1;i<=n;i++)w[i]=read();
dfs(1,0);
id[0]=n*2+1;st[0]=(pi){0,1};
id[dfn+1]=n*2+2;st[dfn+1]=(pi){0,-1};
root=build(0,dfn+1);
int m=read();
while(m--){
char c[5];
scanf("%s",c);
if(c[0]=='Q'){
int x=read();
print(query(x));
printf("\n");
}else if(c[0]=='C'){
int x=read(),y=read();
change(x,y);
}else{
int x=read(),y=read();
modify(x,x+n,y);
}
}
return 0;
}
BZOJ3786 星系探索 【Splay维护dfs序】*的更多相关文章
- bzoj3786星系探索(splay维护dfs序)
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- 【BZOJ 3729】3729: Gty的游戏 (Splay维护dfs序+博弈)
未经博主同意不得转载 3729: Gty的游戏 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 448 Solved: 150 Description ...
- BZOJ3786: 星系探索 Splay+DFS序
题目大意:给你一个树,支持三种操作,子树加,点到根的路径和,改变某一个点的父亲. 分析: 看起来像一个大LCT,但是很显然,LCT做子树加我不太会啊... 那么,考虑更换一个点的父亲这个操作很有意思, ...
- bzoj3786星系探索 splay
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1314 Solved: 425[Submit][Status][Discuss ...
- BZOJ 3729 splay维护DFS序+博弈论
思路: 这像是 阶梯Nim之类的东西 我们 直接把sg函数 设成mod(L+1)的 一棵子树 向下的奇数层上的石子xor起来 就是答案 有加点和改值的操作 就splay维护一下 //By Sirius ...
- BZOJ3786:星系探索(Splay,括号序)
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- BZOJ 3786 星系探索 (splay+dfs序)
题目大意:给你一棵树,支持一下三种操作 1.获取某节点到根节点的路径上所有节点的权值和 2.更换某棵子树的父亲 3.某子树内所有节点的权值都增加一个值w 当时想到了splay维护dfs序,查完题解发现 ...
- [BZOJ3786]星系探索(伪ETT)
3786: 星系探索 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1638 Solved: 506[Submit][Status][Discuss ...
- BZOJ 3786 星系探索 ——Splay
子树可以移动,唔. 还是用Splay维护DFS序即可. 子树的话直接截取出来就好了. 然后求前驱后继可能麻烦一些. 添加两个虚拟节点会比较好写. #include <map> #inclu ...
随机推荐
- maven笔记(3)
项目管理利器(Maven)——Pom.xml解析 <name>项目的描述名</name> <url>项目的地址</url> <descriptio ...
- 1004: [HNOI2008]Cards burnside定理
https://www.lydsy.com/JudgeOnline/problem.php?id=1004 输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,且对每种洗牌法,都存在一种洗牌法使 ...
- 搞懂分布式技术4:ZAB协议概述与选主流程详解
搞懂分布式技术4:ZAB协议概述与选主流程详解 ZAB协议 ZAB(Zookeeper Atomic Broadcast)协议是专门为zookeeper实现分布式协调功能而设计.zookeeper主要 ...
- 【Python】__all__ 暴露接口
很多东西自己实现起来困难或者写的代码很丑,很多时候是因自己对python不是很了解. 以下内容转载自:点这里 Python 可以在模块级别暴露接口: __all__ = ["foo" ...
- C# 设计模式巩固 - 简单工厂模式
前言 设计模式的文章很多.鄙人不才文笔也不咋地.写这篇只为巩固下基础知识,万一不小心帮到了您,是我莫大的荣幸!写的不好欢迎码友指正,废话结束开始进入正题. 介绍 - 简单工厂模式 官方定义:(尴尬~貌 ...
- Prism 4 文档 ---第7章 组成用户界面
一个应用程序的用户界面(UI)可以通用以下几种模式之一来构建: 窗体所需要所有的控件都包含在一个单独的XAML文件中,在设计时组合这个窗体. 窗体的逻辑区域被分割到单独的部分中,通常指哟过户控件.这些 ...
- 虚拟机中centos7与物理主机通讯
本地物理机 WIN命令行:ipconfig 查看网络配置 在物理机的网络配置--> 配置VMnet8 打开VMware 编辑虚拟机设置,选择自定义NAT模式(VMnat8) 编辑->虚拟 ...
- Git 之 问题集锦
准备:远程仓库名:origin 远程分支:master.tt 本地分支:master.test 1. error: src refspec *** does not match an ...
- Inception 初探
1,安装 下载组件 wget clone https:/github.com/mysql-inception/inception.git rz ll unzip inception-master.zi ...
- HBase架构解析
Hbase组件  客户端Client 整个HBase集群的入口 使用HBase RPC机制与HMaster和HRegionserver通信 与HMaster通信进行管理类的操作 与HRegionse ...