[BZOJ 2759] 一个动态树好题

题目描述

首先这是个基环树。

然后根节点一定会连出去一条非树边。通过一个环就可以解除根的答案,然后其他节点的答案就可以由根解出来。

因为要修改\(p_i\),所以我们用\(lct\)。

还是有点难写的。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 30005
#define ls ch[v][0]
#define rs ch[v][1] using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;} const ll mod=10007;
ll inv[mod];
int n;
int k[N],b[N];
int p[N];
int fa[N],ch[N][2];
int rev[N];
int A[N],B[N];
int val[N];
void update(int v) {
A[v]=(A[ls]*k[v])%mod;
B[v]=(B[ls]*k[v]+b[v])%mod;
A[v]=(A[v]*A[rs])%mod;
B[v]=(B[v]*A[rs]+B[rs])%mod;
} bool isroot(int v) {return v!=ch[fa[v]][0]&&v!=ch[fa[v]][1];} void rot(int v) {
int f=fa[v],gr=fa[f];
int sn=v==ch[f][1],son=ch[v][!sn];
if(!isroot(f)) ch[gr][f==ch[gr][1]]=v;
ch[f][sn]=son,ch[v][!sn]=f;
fa[v]=gr,fa[f]=v;
if(son) fa[son]=f;
update(f),update(v);
} void splay(int v) {
while(!isroot(v)) {
int f=fa[v],gr=fa[f];
if(!isroot(f)) rot(f==ch[gr][1]^v==ch[f][1]?f:v);
rot(v);
}
} void access(int v) {
int tem=0;
while(v) {
splay(v);
rs=tem;
update(v);
tem=v,v=fa[v];
}
} int Find_root(int v) {
access(v);
splay(v);
while(ls) v=ls;
return v;
} void Link(int v,int f) {
splay(v);
fa[v]=f;
} void Cut(int v) {
access(v),splay(v);
fa[ls]=0;
ls=0;
update(v);
} void dfs(int v) {
if(!v) return ;
dfs(ls),dfs(rs);
} void work(int v) {
access(p[v]);
splay(p[v]);
int na=A[p[v]]%mod;
int nb=B[p[v]]%mod;
na=(1-na+mod)%mod;
if(!na) {
if(!nb) val[v]=-2;
else val[v]=-1;
} else val[v]=inv[na]*nb%mod;
} int query(int v) {
int rt=Find_root(v);
access(v),splay(v);
if(val[rt]<0) return val[rt];
else return (val[rt]*A[v]+B[v])%mod;
} void modify(int v) {
int top=Find_root(v);
Cut(v);
k[v]=Get(),p[v]=Get(),b[v]=Get();
update(v);
if(Find_root(v)!=Find_root(p[v])) Link(v,p[v]);
if(Find_root(top)!=Find_root(p[top])) Link(top,p[top]);
work(Find_root(v)),work(Find_root(top));
} int main() {
A[0]=1;
inv[0]=inv[1]=1;
for(int i=2;i<mod;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;
n=Get();
for(int i=1;i<=n;i++) {
k[i]=Get(),p[i]=Get(),b[i]=Get();
update(i);
}
for(int i=1;i<=n;i++) {
if(Find_root(i)!=Find_root(p[i])) Link(i,p[i]);
}
for(int i=1;i<=n;i++) if(i==Find_root(i)) work(i); int m=Get();
char op;
int tim=0;
while(m--) {
while(op=getchar(),!isalpha(op));
int a;
if(op=='A') {
a=Get();
cout<<query(a)<<"\n";
} else {
a=Get();
modify(a);
}
} return 0;
}

[BZOJ 2759] 一个动态树好题的更多相关文章

  1. bzoj 2759一个动态树好题

    真的是动态树好题,如果把每个点的父亲设成p[x],那么建出来图应该是一个环套树森林,拆掉一条边,就变成了动态树,考虑维护什么,对于LCT上每个节点,维护两组k和b,一组是他到他父亲的,一组是他LCT子 ...

  2. BZOJ 2759 一个动态树好题(动态树)

    题意 https://www.lydsy.com/JudgeOnline/problem.php?id=2759 思路 每个节点仅有一条有向出边, 这便是一棵基环内向树,我们可以把它在 \(\text ...

  3. 【刷题】BZOJ 2759 一个动态树好题

    Description 有N个未知数x[1..n]和N个等式组成的同余方程组: x[i]=k[i]*x[p[i]]+b[i] mod 10007 其中,k[i],b[i],x[i]∈[0,10007) ...

  4. BZOJ 2759 一个动态树好题 (LCT)

    PoPoQQQ 再一次orz-没看得特别明白的可以回来看看蒟蒻的补充口胡 我这里提一下关于splaysplaysplay维护的子树信息- 在原树上考虑,对于每一个点iii都有这样一个信息xi=ki∗x ...

  5. BZOJ2759: 一个动态树好题

    BZOJ2759: 一个动态树好题 Description 有N个未知数x[1..n]和N个等式组成的同余方程组:x[i]=k[i]*x[p[i]]+b[i] mod 10007其中,k[i],b[i ...

  6. BZOJ2759 一个动态树好题 LCT

    题解: 的确是动态树好题 首先由于每个点只有一个出边 这个图构成了基环内向树 我们观察那个同余方程组 一旦形成环的话我们就能知道环上点以及能连向环上点的值是多少了 所以我们只需要用一种结构来维护两个不 ...

  7. BZOJ2759一个动态树好题 LCT

    题如其名啊 昨天晚上写了一发忘保存 只好今天又码一遍了 将题目中怕$p[i]$看做$i$的$father$ 可以发现每个联通块都是一个基环树 我们对每个基环删掉环上一条边 就可以得到一个森林了 可以用 ...

  8. 【bzoj2759】一个动态树好题

    Portal -->bzoj2759 Solution 哇我感觉这题真的qwq是很好的一题呀qwq 很神qwq反正我真的是自己想怎么想都想不到就是了qwq 首先先考虑一下简化版的问题应该怎么解决 ...

  9. bzoj 2631: tree 动态树+常数优化

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1716  Solved: 576[Submit][Status] Descrip ...

随机推荐

  1. JavaScript 获取按键,并屏蔽系统 Window 事件

    // JavaScript 获取按键,并屏蔽系统 Window 事件 window.document.onkeydown = onkeydown; function onkeydown(event) ...

  2. html 三列布局(两列自适应,一列固定宽度)

    不做过多解释:主要是记录一个完整的布局样式,实现页面大致三列其中左右两列是自适应宽度,中间固定宽度效果. 不多少代码奉上: CSS样式代码: /******************** *公共标签样式 ...

  3. 【WebSocket No.3】使用WebSocket协议来做服务器

    写在开始 上面一篇写了一篇使用WebSocket做客户端,然后服务端是socke代码实现的.传送门:webSocket和Socket实现聊天群发 本来我是打算写到一章上的,毕竟实现的都是一样的功能,后 ...

  4. HTML设为首页/加入收藏代码

    (特别注意:要把'这个符号换成无任何输入法状态中输入的'这个符号,否则程序无法运行)   1.文字型:     <a onclick="this.style.behavior='url ...

  5. js 判断数组中的值是否都相等

    function isAllEqual(array) { if (array.length > 0) { return !array.some(function(value, index) { ...

  6. 贝塞尔曲线与CSS3动画、SVG和canvas的应用

    简介 贝塞尔曲线是可以做出很多复杂的效果来的,比如弹跳球的复杂动画效果,首先加速下降,停止,然后弹起时逐渐减速的效果. 使用贝塞尔曲线常用的两个网址如下: 缓动函数:http://www.xuanfe ...

  7. Android 程序崩溃之后fragment出现画面重叠问题

    1.解决方法: 直接在包含Fragment的Activity中复写onSaveInstanceState()方法,使其空实现 @Override protected void onSaveInstan ...

  8. Python基础知识点

    自学记录: 1.字符串 python中单引号和双引号使用完全相同. 使用三引号('''或""")可以指定一个多行字符串. 转义符 '\' 反斜杠可以用来转义,使用r可以让 ...

  9. 将html前端代码提取公因数(5)

    将html前端代码提取公因数(5) 注意:这是优化html代码,对于多个html代码相同的部分提取到一个模板中,只需要编写变化的html 1,利用Django提供的render方法的第三个参数的属性 ...

  10. C#:读取视频的宽度和高度等信息

    读取方式:使用ffmpeg读取,所以需要先下载ffmpeg.网上资源有很多. 通过ffmpeg执行一条CMD命令可以读取出视频的帧高度和帧宽度信息. 如图: 蓝线框中可以看到获取到的帧高度和帧宽度. ...