BZOJ2759 一个动态树好题 LCT
题解:
的确是动态树好题
首先由于每个点只有一个出边
这个图构成了基环内向树
我们观察那个同余方程组
一旦形成环的话我们就能知道环上点以及能连向环上点的值是多少了
所以我们只需要用一种结构来维护两个不是直接相连点的状态
由于有删边连边操作,比较容易想到lct
我们按照套路将它拆掉一条边形成一颗树
因为我们现在只知道环上某一点的值,所以我们这棵树应该是不随便换根的
每次询问只需要把当前这个点access再splay一下 查询用根怎么表示就可以了
修改方程组等价于删一条边,连一条边
删的边如果不在环上 直接删
#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define mep(x,y) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
namespace IO{
char ss[<<],*A=ss,*B=ss;
IL char gc()
{
return A==B&&(B=(A=ss)+fread(ss,,<<,stdin),A==B)?EOF:*A++;
}
template<class T> void read(T &x)
{
rint f=,c; while (c=gc(),c<||c>) if (c=='-') f=-; x=(c^);
while (c=gc(),c>&&c<) x=(x<<)+(x<<)+(c^); x*=f;
}
template<class T>void read2(T &x)
{
rint c;
while (c=gc(),c!='A'&&c!='C'); x=c;
}
char sr[<<],z[]; ll Z,C1=-;
template<class T>void wer(T x)
{
if (x<) sr[++C1]='-',x=-x;
while (z[++Z]=x%+,x/=);
while (sr[++C1]=z[Z],--Z);
}
IL void wer1()
{
sr[++C1]=' ';
}
IL void wer2()
{
sr[++C1]='\n';
}
template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
template<class T>IL T MAX(T x,T y){return x>y?x:y;}
template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
const int N=5e4;
int k[N],p[N],b[N];
const int mo=;
struct re{
int a,b;
re operator *(const re o) const
{
re c;
c.a=a*o.a%mo; c.b=(o.a*b+o.b)%mo;
return c;
}
};
IL int fsp(int x,int y)
{
int now=;
while (y)
{
if (y&) now=now*x%mo;
x=x*x%mo; y>>=;
}
return now;
}
struct lct{
int ls[N],fa[N],rs[N],sp[N],ans[N];
re sum[N],v[N];
IL void updata(int x)
{
if (ls[x]) sum[x]=sum[ls[x]]*v[x];
else sum[x]=v[x];
if (rs[x]) sum[x]=sum[x]*sum[rs[x]];
}
IL bool pd(int x)
{
return ls[fa[x]]==x||rs[fa[x]]==x;
}
void rotate(int x,int y)
{
int f1=fa[x];
if (y==)
{
rs[f1]=ls[x];
if (ls[x]) fa[ls[x]]=f1;
} else
{
ls[f1]=rs[x];
if (rs[x]) fa[rs[x]]=f1;
}
fa[x]=fa[f1];
if (pd(f1))
{
if (ls[fa[f1]]==f1) ls[fa[f1]]=x;
else rs[fa[f1]]=x;
}
if (y==) ls[x]=f1; else rs[x]=f1;
fa[f1]=x;
updata(f1); updata(x);
}
void splay(int x)
{
// dfs(x);
int f1=fa[x];
while (pd(x))
{
if (!pd(f1))
{
if (ls[f1]==x) rotate(x,); else rotate(x,);
} else
if (ls[fa[f1]]==f1)
if (ls[f1]==x) rotate(f1,),rotate(x,);
else rotate(x,),rotate(x,);
else
if (rs[f1]==x) rotate(f1,),rotate(x,);
else rotate(x,),rotate(x,);
f1=fa[x];
}
}
void access(int x)
{
for (int y=;x;y=x,x=fa[x])
{
splay(x); rs[x]=y; updata(x);
}
}
int fdr(int x)
{
access(x); splay(x);
while (ls[x]) x=ls[x];
return x;
}
int query(int x)
{
access(x); splay(x);
int ro=fdr(x);
re kk=sum[x];
access(sp[ro]);
splay(sp[ro]);
int ans,a=sum[sp[ro]].a,b=sum[sp[ro]].b;
if (a==)
if (b==) ans=-; else ans=-;
ans=(fsp((-a),mo-)*b%mo+mo)%mo;
if (ans==-) return(-);
if (ans==-) return(-);
return ((ans*kk.a+kk.b)%mo+mo)%mo;
}
IL void cut(int x)
{
access(x); splay(x); ls[x]=fa[ls[x]]=; updata(x);
}
void change(int x,int k,int p,int b)
{
int rt=fdr(x);
if (x==rt)
{
if (fdr(p)!=x)
{
sp[x]=; fa[x]=p;
} else
{
sp[x]=p;
}
} else
{
access(sp[rt]); splay(sp[rt]);
int z=x;
while (pd(z)) z=fa[z];
if (z==sp[rt])
{
cut(x);
access(rt); splay(rt); fa[rt]=sp[rt]; sp[rt]=;
} else
{
cut(x);
}
if (fdr(p)!=x)
{
fa[x]=p;
} else
{
sp[x]=p;
}
}
v[x]=(re){k,b}; splay(x);
}
IL void link(int x,int y)
{
if (fdr(x)!=fdr(y))
{
fa[x]=y;
} else sp[x]=y;
}
}S;
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int n;
IO::read(n);
rep(i,,n)
{
IO::read(k[i]),IO::read(p[i]),IO::read(b[i]);
S.v[i]=(re){k[i],b[i]};
S.link(i,p[i]);
}
int q;
IO::read(q);
rep(i,,q)
{
char c;
IO::read2(c);
if (c=='A')
{
int a;
IO::read(a);
IO::wer(S.query(a)); IO::wer2();
} else
{
int a,b,c,d;
IO::read(a); IO::read(b); IO::read(c); IO::read(d);
S.change(a,b,c,d);
}
}
fwrite(IO::sr,,IO::C1+,stdout);
return ;
}
删的边如果在环上 并且没有连上 把标记清除
删的边如果在环上 并且连上了 把这条边段删了,然后把标记边连上
BZOJ2759 一个动态树好题 LCT的更多相关文章
- BZOJ2759一个动态树好题 LCT
题如其名啊 昨天晚上写了一发忘保存 只好今天又码一遍了 将题目中怕$p[i]$看做$i$的$father$ 可以发现每个联通块都是一个基环树 我们对每个基环删掉环上一条边 就可以得到一个森林了 可以用 ...
- BZOJ2759: 一个动态树好题
BZOJ2759: 一个动态树好题 Description 有N个未知数x[1..n]和N个等式组成的同余方程组:x[i]=k[i]*x[p[i]]+b[i] mod 10007其中,k[i],b[i ...
- BZOJ 2759 一个动态树好题 (LCT)
PoPoQQQ 再一次orz-没看得特别明白的可以回来看看蒟蒻的补充口胡 我这里提一下关于splaysplaysplay维护的子树信息- 在原树上考虑,对于每一个点iii都有这样一个信息xi=ki∗x ...
- [BZOJ 2759] 一个动态树好题
[BZOJ 2759] 一个动态树好题 题目描述 首先这是个基环树. 然后根节点一定会连出去一条非树边.通过一个环就可以解除根的答案,然后其他节点的答案就可以由根解出来. 因为要修改\(p_i\),所 ...
- bzoj 2759一个动态树好题
真的是动态树好题,如果把每个点的父亲设成p[x],那么建出来图应该是一个环套树森林,拆掉一条边,就变成了动态树,考虑维护什么,对于LCT上每个节点,维护两组k和b,一组是他到他父亲的,一组是他LCT子 ...
- 【bzoj2759】一个动态树好题
Portal -->bzoj2759 Solution 哇我感觉这题真的qwq是很好的一题呀qwq 很神qwq反正我真的是自己想怎么想都想不到就是了qwq 首先先考虑一下简化版的问题应该怎么解决 ...
- 【刷题】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) ...
- BZOJ 2759 一个动态树好题(动态树)
题意 https://www.lydsy.com/JudgeOnline/problem.php?id=2759 思路 每个节点仅有一条有向出边, 这便是一棵基环内向树,我们可以把它在 \(\text ...
- 动态树Link-cut tree(LCT)总结
动态树是个好玩的东西 LCT题集 预备知识 Splay 树链剖分(好像关系并不大) 动态树(Link-cut tree) 先搬dalao博客 什么是LCT? 动态树是一类要求维护森林的连通性的题的总称 ...
随机推荐
- vim命令替换操作
替换当前行第一个 vivian为sky :s/vivian/sky/ 替换当前行所有 vivian为sky :s/vivian/sky/g 替换第 n 行开始到最后一行中,每一行的第一个vivian为 ...
- Mybatis技术原理理——整体流程理解
前言:2018年,是最杂乱的一年!所以你看我的博客,是不是很空! 网上有很多关于Mybatis原理介绍的博文,这里介绍两篇我个人很推荐的博文 Mybatis3.4.x技术内幕和 MyBaits源码分析 ...
- 2018-2019-2 网络对抗技术 20165232 Exp2 后门原理与实践
2018-2019-2 网络对抗技术 20165232 Exp2 后门原理与实践 1. 后门原理与实践实验说明及预备知识 一.实验说明 任务一:使用netcat获取主机操作Shell,cron启动 ( ...
- Vue学习笔记二:v-cloak,v-text,v-html的使用
目录 v-cloak:解决插值表达式闪烁问题 安装插件Live Server 右键以HTTP形式运行HTML v-text:以属性方式使用插值表达式 v-cloak和v-text的区别 v-html: ...
- Apache Shiro Java反序列化漏洞分析
1. 前言 最近工作上刚好碰到了这个漏洞,当时的漏洞环境是: shiro-core 1.2.4 commons-beanutils 1.9.1 最终利用ysoserial的CommonsBeanuti ...
- Windows 10 上编译 Hadoop
下载源码 源码下载地址(Source download):https://hadoop.apache.org/releases.html 这里以 2.9.2 为例,查看源码中的编译说明文件 BUILD ...
- HTTP协议6之状态码--转
HTTP状态码,我都是现查现用. 我以前记得几个常用的状态码,比如200,302,304,404, 503. 一般来说我也只需要了解这些常用的状态码就可以了. 如果是做AJAX,REST,网络爬虫, ...
- c编译动态库可以编译但是无法导入解决方法
$(CC) $(CFLAGS) -Wl,--whole-archive ${libusb} -Wl,--no-whole-archive $(lib_objs) $(LFLAGS) -o $(lib) ...
- 【转】Redis学习笔记(五)如何用Redis实现分布式锁(2)—— 集群版
原文地址:http://bridgeforyou.cn/2018/09/02/Redis-Dsitributed-Lock-2/ 单机版实现的局限性 在上一篇文章中,我们讨论了Redis分布式锁的实现 ...
- 微信退款时候报”请求被中止: 未能创建 SSL/TLS 安全通道“或”The request was aborted: Could not create SSL/TLS secure channel“的错误
如题,英文中文表述的是一个意思 退款测试在我本机测试一切都是正常的,但是发布到了服务器就报这样的一个错啦 但是无论百度或者google或者bing,你能够搜索到的结果都很类似,综合起来就是加这样一些代 ...