#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. BZOJ 4003 【JLOI2015】城池攻占

    Description 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑士攻占 n 个城池. 这 n 个城池用 1 到 n 的整数表示.除 1 号城池外,城池 i 会受到另一座城池 fi 的管辖, ...

  2. 微软职位内部推荐-Senior Software Engineer_Azure

    微软近期Open的职位: Job Title: Senior Software Engineer Location: Shanghai, China Have you ever imagined th ...

  3. filestream read方法 循环读取固定文件

    1.循环读取啊,byte[]可以定义为1024或者2049等等,不要超过int的maxvalue就可以.然后取出来操作完再去取. FileStream stream = new FileStream( ...

  4. UC~移动端的IE!!!坑总结

    1.接入过WAP版支付宝支付的应该会发现,支付宝页面在UC中巨丑,完全就是诺基亚时代的网页.你可能会怪它是支付宝的问题吧.但你用QQ浏览器打开,很好啊:你在电脑用火狐.Chrome打开都很好啊:那你试 ...

  5. Reflection和Expression Tree解析泛型集合快速定制特殊格式的Json

    很多项目都会用到Json,而且大部分的Json都是格式固定,功能强大,转换简单等,标准的key,value集合字符串:直接JsonConvert.SerializeObject(List<T&g ...

  6. Linux下网络流量实时监控工具

    Linux下网络流量实时监控工具大全 在工作中发现,经常因为业务的原因,需要即时了解某台服务器网卡的流量,虽然公司也部署了cacti软件,但cacti是五分钟统计的,没有即时性,并且有时候打开监控页面 ...

  7. SQL Server output子句用法 output inserted.id 获取刚插入数据的id

    --插入数据,并返回刚刚插入的数据id INSERT INTO [soloreztest] ([name]) output inserted.id VALUES ('solorez') --执行结果: ...

  8. Matlab生成M序列的伪随机码

    伪随机编码中较常用的是m序列,它是线性反馈移位寄存器序列的一种,其特点是在相同寄存器级数的情况下输出序列周期最长.线性反馈移位寄存器的工作原理是,给定所有寄存器一个初始值,当移位脉冲到来时,将最后一级 ...

  9. 为Mac Terminal设置代理

    参考链接:http://tz101.github.io/new-mac-os-x-yosemite-10-10-Xcode-Brew-Shadowsocks-Proxychains/ https:// ...

  10. LVS+Redis部署手册

    Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案. Redis从它的许多竞争继承来的三个主要特点: Redis数据库完全在内存中,使用磁盘仅用 ...