#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. 转:小白编译openwrt固件教程

    原文地址 编译openwrt固件并没有想象的那么复杂,我也是个小白,以下内容是我将网络上的编译教程稍微进行了一下整合.因为我发现很多编译教程没有说明如何更改flash相关配置.   安装ubuntu, ...

  2. 设置 java -jar 的进程显示名称

    有时候我们会用 nohup java -jar xxx.jar来将一些可执行的java application挂在后台,类似windows服务一样来运行.但是有一个不爽的地方,在linux终端里用jp ...

  3. C#以post方式调用struts rest-plugin service的问题

    struts2: 玩转 rest-plugin一文中,学习了用struts2开发restful service的方法,发现用c#以post方式调用时各种报错,但java.ajax,包括firefox ...

  4. 扩展 easyui-tabs 插件 关闭标签页方法

    $.extend($.fn.tabs.methods,{ allTabs:function(jq){ var tabs = $(jq).tabs('tabs'); var all = []; all ...

  5. Tomcat 项目部署方式

    方法一:在Tomcat中的Conf目录中,在Server.Xml中的,<Host/>节点中添加: <Context Path="/Hello"Docbase=&q ...

  6. APP架子迁移指南(二)

    接上一篇,这一篇开始用android来解释MVP概念.八股式的架子结构和命名规范.我在准备这篇文章的时候还看到不少在MVP基础上衍生的架子思路,底子是MVP没错,但命名有区别.复杂度变了.架子也用到了 ...

  7. Android开发自学笔记(Android Studio1.3.1)—3.Android应用结构解析

    一.R文件是什么?      如上图所示,我们可以通过findViewById方法通过传入R.id.show找到我们的TextView元素,findViewById方法也很好理解,从View中通过Id ...

  8. SQLite常用点滴总结(转)

    expressionexpr ::=     expr binary-op expr |expr [NOT] like-op expr [ESCAPE expr] |unary-op expr |( ...

  9. 关于document.getElement获取元素返回值的问题

    获取网页元素有很多种方法,如下: document.all[];返回HTMLElement对象 document.all.tags[];返回NodeList对象,类似数组 document.getEl ...

  10. 【SQL语句】 - Ctrl+3 查询表属性的存储过程

    /**-- ============================================= Author: xft CteateDate: 2013-10-11 Description:查 ...