LUOGU P1501 [国家集训队]Tree II (lct)
##解题思路
\(lct\),比较模板的一道题,路径加和乘的维护标记与线段树$2$差不多,然后剩下就没啥了。但调了我将近一下午。。
##代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN = 100005;
const int MOD = 51061;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
}
int n,q,fa[MAXN],sum[MAXN],ch[MAXN][2],w[MAXN];
int tag_mul[MAXN],tag_add[MAXN],siz[MAXN];
bool tag[MAXN];
inline void pushup(int x){
sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+w[x];sum[x]%=MOD;
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
}
inline bool isroot(int x){
return (x!=ch[fa[x]][0] && x!=ch[fa[x]][1]);
}
inline bool check(int x){
return (x==ch[fa[x]][1]);
}
inline void pushdown(int x){
if(tag[x]){
if(ch[x][0]) tag[ch[x][0]]^=1,swap(ch[ch[x][0]][0],ch[ch[x][0]][1]);
if(ch[x][1]) tag[ch[x][1]]^=1,swap(ch[ch[x][1]][0],ch[ch[x][1]][1]);
tag[x]=0;
}
if(tag_mul[x]!=-1){
if(ch[x][0]){
if(tag_add[ch[x][0]]!=-1) (tag_add[ch[x][0]]*=tag_mul[x])%=MOD;
if(tag_mul[ch[x][0]]==-1) tag_mul[ch[x][0]]=tag_mul[x];
else (tag_mul[ch[x][0]]*=tag_mul[x])%=MOD;
w[ch[x][0]]*=tag_mul[x];w[ch[x][0]]%=MOD;
sum[ch[x][0]]*=tag_mul[x];sum[ch[x][0]]%=MOD;
}
if(ch[x][1]){
if(tag_add[ch[x][1]]!=-1) (tag_add[ch[x][1]]*=tag_mul[x])%=MOD;
if(tag_mul[ch[x][1]]==-1) tag_mul[ch[x][1]]=tag_mul[x];
else (tag_mul[ch[x][1]]*=tag_mul[x])%=MOD;
w[ch[x][1]]*=tag_mul[x];w[ch[x][1]]%=MOD;
sum[ch[x][1]]*=tag_mul[x];sum[ch[x][1]]%=MOD;
}
tag_mul[x]=-1;
}
if(tag_add[x]!=-1) {
if(ch[x][0]) {
if(tag_add[ch[x][0]]==-1) tag_add[ch[x][0]]=tag_add[x];
else (tag_add[ch[x][0]]+=tag_add[x])%=MOD;
(w[ch[x][0]]+=tag_add[x])%=MOD;
sum[ch[x][0]]+=siz[ch[x][0]]*tag_add[x];sum[ch[x][0]]%=MOD;
}
if(ch[x][1]){
if(tag_add[ch[x][1]]==-1) tag_add[ch[x][1]]=tag_add[x];
else (tag_add[ch[x][1]]+=tag_add[x])%=MOD;
(w[ch[x][1]]+=tag_add[x])%=MOD;
sum[ch[x][1]]+=siz[ch[x][1]]*tag_add[x];sum[ch[x][1]]%=MOD;
}
tag_add[x]=-1;
}
}
inline void update(int x){
if(!isroot(x)) update(fa[x]);pushdown(x);
}
inline void rotate(int x){
int y=fa[x],z=fa[y];bool chk=check(x);
if(!isroot(y)) ch[z][y==ch[z][1]]=x;
ch[y][chk]=ch[x][chk^1];fa[ch[x][chk^1]]=y;
fa[y]=x;ch[x][chk^1]=y;fa[x]=z;
pushup(y);pushup(x);
}
inline void splay(int x){
update(x);
for(;!isroot(x);rotate(x))
if(!isroot(fa[x])) rotate(check(fa[x])==check(x)?fa[x]:x);
}
inline void access(int x){
for(int y=0;x;y=x,x=fa[x])
splay(x),ch[x][1]=y,pushup(x);
}
inline int findroot(int x){
access(x);splay(x);
while(ch[x][0]) pushdown(x),x=ch[x][0];
return x;
}
inline void makeroot(int x){
access(x);splay(x);
tag[x]^=1;swap(ch[x][0],ch[x][1]);
}
inline void split(int x,int y){
makeroot(x);access(y);splay(y);
}
inline void link(int x,int y){
if(findroot(x)==findroot(y)) return;
makeroot(x);fa[x]=y;
}
inline void cut(int x,int y){
if(findroot(x)!=findroot(y)) return;
split(x,y);
if(ch[y][0]==x && !ch[x][1])
fa[x]=0,ch[y][0]=0,pushup(y);
}
inline void update_add(int x,int y,int k){
split(x,y);
if(tag_add[y]!=-1) (tag_add[y]+=k)%=MOD ;else tag_add[y]=k;
w[y]+=k;pushup(y);w[y]%=MOD;
}
inline void update_mul(int x,int y,int k){
split(x,y);
if(tag_add[y]!=-1) (tag_add[y]*=k)%=MOD;
if(tag_mul[y]!=-1) (tag_mul[y]*=k)%=MOD;else tag_mul[y]=k;
w[y]*=k;pushup(y);w[y]%=MOD;
}
signed main(){
memset(tag_mul,-1,sizeof(tag_mul));
memset(tag_add,-1,sizeof(tag_add));
int x,y,a,b;char c;n=rd(),q=rd();
for(int i=1;i<=n;i++) w[i]=1;
for(int i=1;i<n;i++){
x=rd(),y=rd();
link(x,y);
}
while(q--){
scanf("%c",&c);
if(c=='+'){
x=rd(),y=rd(),a=rd();
update_add(x,y,a);
}
else if(c=='-'){
x=rd(),y=rd(),a=rd(),b=rd();
cut(x,y);link(a,b);
}
else if(c=='*') {
x=rd(),y=rd(),a=rd();
update_mul(x,y,a);
}
else {
x=rd(),y=rd();
split(x,y);printf("%lld\n",sum[y]);
}
}
return 0;
}
LUOGU P1501 [国家集训队]Tree II (lct)的更多相关文章
- BZOJ 2631 tree | Luogu P1501 [国家集训队]Tree II (LCT 多重标记下放)
链接:https://www.luogu.org/problemnew/show/P1501 题面: 题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: ...
- BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)
题意 一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和 分析 LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了 CODE #include<bits/s ...
- 洛谷P1501 [国家集训队]Tree II(LCT)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- P1501 [国家集训队]Tree II LCT
链接 luogu 思路 简单题 代码 #include <bits/stdc++.h> #define ls c[x][0] #define rs c[x][1] using namesp ...
- P1501 [国家集训队]Tree II(LCT)
P1501 [国家集训队]Tree II 看着维护吧2333333 操作和维护区间加.乘线段树挺像的 进行修改操作时不要忘记吧每个点的点权$v[i]$也处理掉 还有就是$51061^2=2607225 ...
- 洛谷 P1501 [国家集训队]Tree II 解题报告
P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...
- 洛谷P1501 [国家集训队]Tree II(LCT,Splay)
洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...
- 洛谷P1501 [国家集训队]Tree II(打标记lct)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- [洛谷P1501] [国家集训队]Tree II(LCT模板)
传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...
随机推荐
- poj 2752 kmp的next数组
题目大意: 求一个字符串中某一个既是前缀又是后缀的前缀的结尾下标: 基本思路: 从_next[len]开始找_next[_next[len]],再找_next[_next[_next[len]]],一 ...
- leetcood学习笔记-14*-最长公共前缀
笔记: python if not 判断是否为None的情况 if not x if x is None if not x is None if x is not None`是最好的写法,清晰,不 ...
- Delphi中的线程类(转)
Delphi中的线程类 (转) Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对 TThread类的几个成员作一简单介绍,再说明一下 ...
- Flex布局(二)
接上一篇,说一下flex布局的实例,转自阮一峰老师的博客
- 【2017 Multi-University Training Contest - Team 8】Hybrid Crystals
[Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6140 [Description] 等价于告诉你有n个物品,每个物品的价值为-a[i]或a[i],或 ...
- img引用网络图片资源无法加载问题解决
近期在自己项目中遇到引用一些网络图片资源,显示无法加载,但是在浏览器打开图片路径又可以显示的问题 解决办法: 在图片显示的界面把meta referrer标签改为never <meta name ...
- NX二次开发-基于NX开发向导模板的NX对Excel读写操作(OLE方式(COM组件))
在看这个博客前,请读者先去完整看完:NX二次开发-基于MFC界面的NX对Excel读写操作(OLE方式(COM组件))https://ufun-nxopen.blog.csdn.net/article ...
- bootstrap 的 datetimepicker,同时有日期和时间, 且开始时间要早于结束时间
首先,引入jquery, bootstrap 和 bootstrap-datetimepicker datetimepicker的下载地址: http://www.bootcss.com/p/boot ...
- Ubuntu下qemu环境搭建vexpress开发平台
在查找资料过程中,发现自己搭建虚拟的arm环境的话,有一个比较好的软件就是qemu了,当然还有其他的,大家各投所好就好. 接下来说一下qemu环境搭建过程. 其实搭建很简单,作为小白,我还是捣鼓了两三 ...
- Java学习之classpath
要运行class文件,必须在class文件所在的目录下,那么是不是也可以通过设置系统变量来配置呢,当然有了classpath就来了 环境变量配置有两种 1.一劳永逸的 2.set 临时变量 我们用临时 ...