点此看题面

大致题意: 有一棵初始边权全为\(1\)的树,四种操作:将两点间路径边权都加上一个数,删一条边、加一条新边,将两点间路径边权都加上一个数,询问两点间路径权值和。

序列版

这道题有一个序列版:【洛谷3373】【模板】线段树 2

看题目就知道是一道线段树板子题。

这种题目移到树上路径中,且要删边加边,是\(LCT\)无疑了。

\(LCT\)维护懒惰标记

可以说,这道题就是上面那题的翻版。

同样维护两个标记:乘法标记加法标记,加上原有的翻转标记,共三个标记。

具体细节其实可以详见上面提到的那道线段树板子题,这里就不多说了。

主要是要注意标记下传与更新的优先级问题,应该是乘法先,加法后,至于翻转标记在前在后都无所谓。

代码

#include<bits/stdc++.h>
#define N 100000
#define MOD 51061
#define swap(x,y) (x^=y^=x^=y)
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
using namespace std;
int n,ee,lnk[N+5];
class Class_FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,Fsize,stdout),Fout[(FoutSize=0)++]=ch))
int Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
Class_FIO() {A=B=Fin;}
inline void read(int &x) {x=0;while(!isdigit(ch=tc()));while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));}
inline void readc(char &x) {while(isspace(x=tc()));}
inline void writeln(int x) {while(Stack[++Top]=x%10+48,x/=10);while(Top) pc(Stack[Top--]);pc('\n');}
inline void clear() {fwrite(Fout,1,FoutSize,stdout),FoutSize=0;}
}F;
class Class_LCT//LCT板子
{
private:
#define LCT_SIZE N
#define PushUp(x) (node[x].Size=node[node[x].Son[0]].Size+node[node[x].Son[1]].Size+1,node[x].Sum=(node[x].Val+node[node[x].Son[0]].Sum+node[node[x].Son[1]].Sum)%MOD)
#define MulVal(x,v) (node[x].Sum=1LL*node[x].Sum*v%MOD,node[x].Val=1LL*node[x].Val*v%MOD,node[x].flag1=1LL*node[x].flag1*v%MOD,node[x].flag2=1LL*node[x].flag2*v%MOD)
#define AddVal(x,v) (Inc(node[x].Sum,1LL*node[x].Size*v%MOD),Inc(node[x].Val,v),Inc(node[x].flag2,v))
#define Rever(x) (swap(node[x].Son[0],node[x].Son[1]),node[x].Rev^=1)
#define PushDown(x)\
(\
node[x].flag1^1&&(MulVal(node[x].Son[0],node[x].flag1),MulVal(node[x].Son[1],node[x].flag1),node[x].flag1=1),\
node[x].flag2&&(AddVal(node[x].Son[0],node[x].flag2),AddVal(node[x].Son[1],node[x].flag2),node[x].flag2=0),\
node[x].Rev&&(Rever(node[x].Son[0]),Rever(node[x].Son[1]),node[x].Rev=0)\
)
#define Which(x) (node[node[x].Father].Son[1]==x)
#define Connect(x,y,d) (node[node[x].Father=y].Son[d]=x)
#define IsRoot(x) (node[node[x].Father].Son[0]^x&&node[node[x].Father].Son[1]^x)
#define MakeRoot(x) (Access(x),Splay(x),Rever(x))
#define Split(x,y) (MakeRoot(x),Access(y),Splay(y))
int Stack[LCT_SIZE+5];
struct Tree
{
int Val,Sum,Size,flag1,flag2,Rev,Father,Son[2];
}node[LCT_SIZE+5];
inline void Rotate(int x)
{
register int fa=node[x].Father,pa=node[fa].Father,d=Which(x);
!IsRoot(fa)&&(node[pa].Son[Which(fa)]=x),node[x].Father=pa,Connect(node[x].Son[d^1],fa,d),Connect(fa,x,d^1),PushUp(fa),PushUp(x);
}
inline void Splay(int x)
{
register int fa=x,Top=0;
while(Stack[++Top]=fa,!IsRoot(fa)) fa=node[fa].Father;
while(Top) PushDown(Stack[Top]),--Top;
while(!IsRoot(x)) fa=node[x].Father,!IsRoot(fa)&&(Rotate(Which(x)^Which(fa)?x:fa),0),Rotate(x);
}
inline void Access(int x) {for(register int son=0;x;x=node[son=x].Father) Splay(x),node[x].Son[1]=son,PushUp(x);}
inline int FindRoot(int x) {Access(x),Splay(x);while(node[x].Son[0]) PushDown(x),x=node[x].Son[0];return Splay(x),x;}
public:
inline void Init(int len) {for(register int i=1;i<=len;++i) node[i].Val=node[i].flag1=1;}
inline void Link(int x,int y) {MakeRoot(x),FindRoot(y)^x&&(node[x].Father=y);}
inline void Cut(int x,int y) {MakeRoot(x),!(FindRoot(y)^x)&&!(node[y].Father^x)&&!node[y].Son[0]&&(node[y].Father=node[x].Son[1]=0,PushUp(x));}
inline void Mul(int x,int y,int v) {Split(x,y),MulVal(y,v);}
inline void Add(int x,int y,int v) {Split(x,y),AddVal(y,v);}
inline int Query(int x,int y) {return Split(x,y),node[y].Sum;}
}LCT;
int main()
{
register int query_tot,i,x,y,z;register char op;
for(F.read(n),F.read(query_tot),LCT.Init(n),i=1;i<n;++i) F.read(x),F.read(y),LCT.Link(x,y);
while(query_tot--)
{
F.readc(op),F.read(x),F.read(y);
switch(op)
{
case '*':F.read(z),LCT.Mul(x,y,z);break;
case '+':F.read(z),LCT.Add(x,y,z);break;
case '-':LCT.Cut(x,y),F.read(x),F.read(y),LCT.Link(x,y);break;
case '/':F.writeln(LCT.Query(x,y));break;
}
}
return F.clear(),0;
}

【洛谷1501】[国家集训队] Tree II(LCT维护懒惰标记)的更多相关文章

  1. 洛谷.1501.[国家集训队]Tree II(LCT)

    题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...

  2. 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree

    [题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...

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

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

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

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

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

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

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

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

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

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

  8. 【刷题】洛谷 P1501 [国家集训队]Tree II

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

  9. [洛谷P1501][国家集训队]Tree II

    题目大意:给一棵树,有四种操作: $+\;u\;v\;c:$将路径$u->v$区间加$c$ $-\;u_1\;v_1\;u_2\;v_2:$将边$u_1-v_1$切断,改成边$u_2-v_2$, ...

  10. 洛谷 P1501 [国家集训队]Tree II

    看来这个LCT板子并没有什么问题 #include<cstdio> #include<algorithm> using namespace std; typedef long ...

随机推荐

  1. Ocelot(二)- 请求聚合与负载均衡

    Ocelot(二)- 请求聚合与负载均衡 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/10865511.html 源码地址: ...

  2. 关于在SSM框架下使用PageHelper

    首先,如果各位在这块配置和代码有什么问题欢迎说出来,我也会尽自己最大的能力帮大家解答 这些代码我都是写在一个小项目里的,项目的github地址为:https://github.com/Albert-B ...

  3. 笔记-迎难而上之Java基础进阶1

    Collection集合 数组的长度是固定的,集合的长度是可变的 数组中存储的是同一类型的元素,可以存储基本数据类型值.集合存储的都是对象.而且对象的类型可以不一致. 集合框架 import java ...

  4. 修改profile出错后的补救

    修改profile出错后的补救,谢天谢地export命令还能用 今天在鼓捣centOS的时候,一不小心把用户配置文件profile给改错啦.重启之后进不了图形界面,终端里的命令也有大半不好使啦. 我试 ...

  5. gulp的watch记事本

    let gulp=require('gulp'), nodemon=require('gulp-nodemon'), browser=require('browser-sync'); let relo ...

  6. 分层图 (可以选择K条路的权为0,求最短路)

    分层图可以处理从图中选取k条边使其边权变为0,求最短路 Description 在你的强力援助下,PCY 成功完成了之前的所有任务,他觉得,现在正是出去浪的大好时光.于是,他来到高速公路上,找到一辆摩 ...

  7. JavaScript跨域资源请求(CORS)解决方案

    跨域:当协议.主域名.子域名.端口号中任意一个不相同时都不算同一个域,而在不同域之间请求数据即为跨域请求.解决方法有以下几种(如有错误欢迎指出)以请求图片url为例: 1.通过XMLHttpReque ...

  8. 错误:正在解析文件 '/var/lib/dpkg/updates/0004'

    sudo rm /var/lib/dpkg/updates/* sudo apt-get update

  9. Kotlin容器

    1. 容器 可变/不可变 List<out T> 只读list; MutableList<T>; Set<out T>/MutableSet<T> Ma ...

  10. Quartz.NET持久化

    Quartz.NET所用到的数据库表结构 官方提供的各种数据库脚本:https://github.com/quartznet/quartznet/tree/master/database/tables ...