点此看题面

大致题意: 有一棵初始边权全为\(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. PAT1060【大模拟啊】

    怎么麻烦怎么来了??? 提供几个案例: 5 0.00001 0.00001 0 0.0 0.0222 1 0.001 0.2000 2 005.06 0.230 1 00.020 0 贴份代码跑.. ...

  2. 2.python中的矩阵、多维数组----numpy

    最近在将一个算法由matlab转成python,初学python,很多地方还不熟悉,总体感觉就是上手容易,实际上很优雅地用python还是蛮难的.目前为止,觉得就算法仿真研究而言,还是matlab用得 ...

  3. 《OD大数据实战》Mahout入门实例

    一.环境搭建 1. 下载 mahout-0.9-cdh5.3.6.tar.gz 2. 解压 3. mahout org.apache.mahout.clustering.syntheticcontro ...

  4. ALSA声音编程

    1. ALSA设备驱动将ALSA设备描述分为四层,从上到下为: default default:0 plughw:0,0 hw:0,0 不同的层次,对设备的控制权限不同,比如hardware para ...

  5. k8s yaml文件详解

    1.yaml格式的Pod配置文件内容及注解 深入Pod之前,首先我们来了解下Pod的yaml整体文件内容及功能注解. 如下: # yaml格式的pod定义文件完整内容: apiVersion: v1 ...

  6. Mysql常见问题集锦

    缺少libstdc++.so.6库的原因及解决办法 https://blog.csdn.net/u010417185/article/details/69951312 https://www.cnbl ...

  7. heapq模块

    该模块提供了堆排序算法的实现.堆是二叉树,最大堆中父节点大于或等于两个子节点,最小堆父节点小于或等于两个子节点. 创建堆 heapq有两种方式创建堆, 一种是使用一个空列表,然后使用heapq.hea ...

  8. Codeforces Round #363 (Div. 2) A

     Description There will be a launch of a new, powerful and unusual collider very soon, which located ...

  9. aspnetcore的中间件

    Run会终止中间件继续传递 app.Run(new RequestDelegate(async context => { await Task.Run(() => { context.Re ...

  10. vector的学习

    学习链接:http://www.runoob.com/cplusplus/cpp-stl-tutorial.html kandaima #include<iostream> #includ ...