传送门

##解题思路
  \(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)的更多相关文章

  1. BZOJ 2631 tree | Luogu P1501 [国家集训队]Tree II (LCT 多重标记下放)

    链接:https://www.luogu.org/problemnew/show/P1501 题面: 题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: ...

  2. BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)

    题意 一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和 分析 LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了 CODE #include<bits/s ...

  3. 洛谷P1501 [国家集训队]Tree II(LCT)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  4. P1501 [国家集训队]Tree II LCT

    链接 luogu 思路 简单题 代码 #include <bits/stdc++.h> #define ls c[x][0] #define rs c[x][1] using namesp ...

  5. P1501 [国家集训队]Tree II(LCT)

    P1501 [国家集训队]Tree II 看着维护吧2333333 操作和维护区间加.乘线段树挺像的 进行修改操作时不要忘记吧每个点的点权$v[i]$也处理掉 还有就是$51061^2=2607225 ...

  6. 洛谷 P1501 [国家集训队]Tree II 解题报告

    P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...

  7. 洛谷P1501 [国家集训队]Tree II(LCT,Splay)

    洛谷题目传送门 关于LCT的其它问题可以参考一下我的LCT总结 一道LCT很好的练习放懒标记技巧的题目. 一开始看到又做加法又做乘法的时候我是有点mengbi的. 然后我想起了模板线段树2...... ...

  8. 洛谷P1501 [国家集训队]Tree II(打标记lct)

    题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...

  9. [洛谷P1501] [国家集训队]Tree II(LCT模板)

    传送门 这是一道LCT的板子题,说白了就是在LCT上支持线段树2的操作. 所以我只是来存一个板子,并不会讲什么(再说我也不会,只能误人子弟2333). 不过代码里的注释可以参考一下. Code #in ...

随机推荐

  1. PHP 的 new static 和 new self

    下面我们举个例子: class Father { public static function getSelf() { return new self(); } public static funct ...

  2. v-for 循环 绑定对象 和数组

    <!--v-for 迭代数组--> <div id="app11"> <div v-for="info in infos"> ...

  3. Dart编程实例 - Dart 面向对象编程

    Dart编程实例 - Dart 面向对象编程 class TestClass { void disp() { print("Hello World"); } } void main ...

  4. Python 项目隔离环境virtualenv--venv

    virtualenv 用来为一个应用创建一套“隔离”的python运行环境. 先安装virtualenv: pip3 install virtualenv 再进入项目目录,或者创建一个项目目录并进入, ...

  5. How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04

    How To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04 链接来自于:https://www.digitalo ...

  6. 兼容软件,Wine安装,Crossover安装,

    EL6 (RHEL6 and SL6) Required packages for proper building of 32-bit Wine on 64-bit EL6 yum install - ...

  7. Fiddler设置抓一个域名下个包

    设置抓一个域名下个包 右侧Filters 勾选Use Filters 勾选Hosts 选择 Show only the follwing Hosts  设置好自己的抓包的域名

  8. python轻松实现代码编码格式转换

    python轻松实现代码编码格式转换 最近刚换工作不久,没太多的时间去整理工作中的东西,大部分时间都在用来熟悉新公司的业务,熟悉他们的代码框架了,最主要的是还有很多新东西要学,我之前主要是做php后台 ...

  9. 【Java多线程系列四】控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

  10. Netty 源码学习——EventLoop

    Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...