#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define mod 51061
#define maxn 100005
#define ll unsigned int
using namespace std; int n,q,fa[maxn],son[maxn][],size[maxn];
bool rev[maxn];
ll val[maxn],lazyc[maxn],lazyh[maxn],sum[maxn]; struct date{
int which(int x){
return son[fa[x]][]==x;
}
bool isroot(int x){
return son[fa[x]][]!=x&&son[fa[x]][]!=x;
}
void update(int x){
size[x]=size[son[x][]]+size[son[x][]]+;
sum[x]=val[x]%mod;
if (son[x][]) sum[x]=(sum[x]+sum[son[x][]])%mod;
if (son[x][]) sum[x]=(sum[x]+sum[son[x][]])%mod;
}
void jia(int x,ll y){
lazyh[x]=(lazyh[x]+y)%mod;
val[x]=(val[x]+y)%mod;
sum[x]=(sum[x]+size[x]*y%mod)%mod;
}
void cheng(int x,ll y){
if (lazyh[x]){
lazyh[x]=(lazyh[x]*y)%mod;
}
lazyc[x]=(lazyc[x]*y)%mod;
val[x]=(val[x]*y)%mod;
sum[x]=(sum[x]*y)%mod;
}
void pushdown(int x){
if (rev[x]){
rev[x]^=,swap(son[x][],son[x][]);
if (son[x][]) rev[son[x][]]^=;
if (son[x][]) rev[son[x][]]^=;
}
if (lazyc[x]!=){
if (son[x][]) cheng(son[x][],lazyc[x]);
if (son[x][]) cheng(son[x][],lazyc[x]);
lazyc[x]=;
}
if (lazyh[x]){
if (son[x][]) jia(son[x][],lazyh[x]);
if (son[x][]) jia(son[x][],lazyh[x]);
lazyh[x]=;
}
}
void relax(int x){
if (!isroot(x)) relax(fa[x]);
pushdown(x);
}
void rotata(int x){
int y=fa[x],d=which(x),dd=which(y);
if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
fa[son[x][d^]]=y,son[y][d]=son[x][d^];
fa[y]=x,son[x][d^]=y;
update(y);
}
void splay(int x){
relax(x);
while (!isroot(x)){
if (isroot(fa[x])) rotata(x);
else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
else rotata(x),rotata(x);
}
update(x);
}
void access(int x){
for (int p=;x;x=fa[x]){
splay(x);
son[x][]=p;
update(x);
p=x;
}
}
void make_root(int x){
access(x);
splay(x);
rev[x]^=;
}
void link(int x,int y){
make_root(x),fa[x]=y;
}
void cut(int x,int y){
make_root(x);
access(y);
splay(y);
son[y][]=fa[x]=;
update(y);
}
void split(int x,int y){
make_root(x);
access(y);
splay(y);
}
void add(int x,int y,ll z){
split(x,y);
jia(y,z);
}
void multiply(int x,int y,ll z){
split(x,y);
cheng(y,z);
}
void query(int x,int y){
split(x,y);
printf("%u\n",sum[y]%mod);
}
}lct; int main(){
// freopen("tree.in","r",stdin);
// freopen("tree.out","w",stdout);
char st[];
int u,v,U,V;
ll UU,VV;
memset(size,,sizeof(size));
memset(fa,,sizeof(fa));
memset(son,,sizeof(son));
memset(rev,,sizeof(rev));
scanf("%d%d",&n,&q);
for (int i=;i<=n;i++){
val[i]=,sum[i]=,lazyc[i]=,lazyh[i]=,size[i]=;
}
for (int i=;i<n;i++){
scanf("%d%d",&u,&v);
lct.link(u,v);
}
while (q--){
scanf("%s%d%d",st+,&u,&v);
if (st[]=='+') scanf("%u",&UU),lct.add(u,v,UU);
else if (st[]=='-') scanf("%d%d",&U,&V),lct.cut(u,v),lct.link(U,V);
else if (st[]=='*') scanf("%u",&UU),lct.multiply(u,v,UU);
else lct.query(u,v);
}
return ;
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2631

做法:链乘链加:先传乘标记,并且把加标记乘上这个数,再传加标记;

看个变形就很显然了:(ax+b)*c=a*c*x+b*c,显然加标记也要乘上这个数。

bzoj2631: tree的更多相关文章

  1. BZOJ2631——tree

    1.题目大意:bzoj1798的lct版本 2.分析:这个把线段树改成splay就好 #include <stack> #include <cstdio> #include & ...

  2. [BZOJ2631]tree 动态树lct

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 5171  Solved: 1754[Submit][Status][Discus ...

  3. [Link-Cut-Tree][BZOJ2631]Tree

    题面 Description: 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\(v\)的路径上的点的 ...

  4. bzoj2631 tree LCT 区间修改,求和

    tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 4962  Solved: 1697[Submit][Status][Discuss] Des ...

  5. bzoj2631: tree lct

    要打mul和add的lct 50000+的mod用unsigned int好了TAT (坑爹没打pc('\n');(静态)调了好久,样例竟然只输出一个,orz,也不提示PE T_T) #include ...

  6. BZOJ2631 tree(伍一鸣) LCT 秘制标记

    这个题一看就是裸地LCT嘛,但是我wa了好几遍,这秘制标记...... 注意事项:I.*对+有贡献 II.先下传*再下传+(因为我们已经维护了+,不能再让*对+产生贡献)III.维护+用到size # ...

  7. [bzoj2631]tree——lct

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

  8. BZOJ2631 tree 【LCT】

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

  9. BZOJ2631: tree(LCT)

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

随机推荐

  1. 微软职位内部推荐-SDEII_ ECO

    微软近期Open的职位: SDE II SDE II Organization Summary: Engineering, Customer interactions & Online (EC ...

  2. vue 滚动加载

    <template> <div class="wraper" @scroll="onScroll($event)"> <div c ...

  3. opencv5-objdetect之级联分类器

    这是<opencv2.4.9tutorial.pdf>的objdetect module的唯一一个例子. 在opencv中进行人脸或者人眼 或者身体的检测 首先就是训练好级联分类器,然后就 ...

  4. C“中断” 与 JS“异步回调” 横向对比

    在底层C语言中,有一个非常重要而特别的概念,叫做“中断”.用比喻来说,我正在写着博客,突然我妈打个电话过来,我就离开了键盘去接电话了,然后写博客就中断了,我聊完电话回来再继续写.乍一听似乎并没有什么大 ...

  5. sublime 函数跳转插件 — ctags 安装和使用

    ctags 是 sublime 下一个函数跳转的插件,可以让你方便地从函数调用的位置跳到函数定义的位置.相对于其他插件,ctags 的安装稍微有点复杂,这里记录下备忘. 首先,假设已经安装 Packa ...

  6. Canvas之打字机游戏

    最近针对粒子化作了一点点的探究,决定结合其做个小游戏,于是这个简单的打字游戏出世了. 试玩地址:Typewriter game  仅在chrome下测试,请谨慎使用其他浏览器(特别是ff):加载速度有 ...

  7. android之Activity回传数据

    约定:当Activity发生跳转时将原来的Activity成为父Activity,将新出现的Activity成为子Activity. 情景设置 下面是个发短信的Activity 当我们点击图中的+按钮 ...

  8. hdu1754 I hate it线段树模板 区间最值查询

    题目链接:这道题是线段树,树状数组最基础的问题 两种分类方式:按照更新对象和查询对象 单点更新,区间查询; 区间更新,单点查询; 按照整体维护的对象: 维护前缀和; 维护区间最值. 线段树模板代码 # ...

  9. springMvc接受日期类型参数处理

    这个问题,也即是springMvc如何进行参数类型的转换 以把client传过来一个String类型,转换为日期类型为例: 1.controller /** * 接收日期类型参数 * 注意: * sp ...

  10. Shell脚本编程中的几个问题

    条件语句 正确的写法: if [ $1 = "-f" ] #注意这里,前后方括号和中间的内容之间必须有空格! then commands fi 错误的写法: if [$1 == & ...