题目大意:给你一棵树,让你维护一个数据结构,支持

边的断,连

树链上所有点点权加上某个值

树链上所有点点权乘上某个值

求树链所有点点权和

(辣鸡bzoj又是土豪题,洛谷P1501传送门)

LCT裸题,下传标记,搞法类似于洛谷线段树模板2

先下传乘法标记,val,sum,乘法标记,加法标记都要乘

再下传加法标记,val,加法标记直接加,sum应该加上子树size*加的值

卡了10分钟我发现打标记应该同时更新这个位置的实际值

又卡了10分钟发现我下传完标记忘记清零了

然而我又忘记了一个事情被卡了20分钟!乘法标记能下传的条件是,乘法标记不等于1 而不是 不等于0!!!

智商已下线

 #include <cstdio>
#include <algorithm>
#include <cstring>
#define il inline
#define ui unsigned int
#define mod 51061
#define N 101000
using namespace std; int n,m,tp;
int stk[N];
struct LinkCutTree{
int fa[N],ch[N][],rv[N];
ui sz[N],sum[N],val[N],add[N],mul[N];
il int idf(int x){return ch[fa[x]][]==x?:;}
il void con(int x,int ff,int p){fa[x]=ff,ch[ff][p]=x;}
il int isroot(int x){return (ch[fa[x]][]!=x&&ch[fa[x]][]!=x)?:;}
il void rev(int x){swap(ch[x][],ch[x][]),rv[x]^=;}
il void pushup(int x)
{
sum[x]=(sum[ch[x][]]+sum[ch[x][]]+val[x])%mod;
sz[x]=sz[ch[x][]]+sz[ch[x][]]+;
}
il void pushdown(int x)
{
#define ls ch[x][0]
#define rs ch[x][1]
if(mul[x]!=)
{
sum[ls]=(sum[ls]*mul[x])%mod,sum[rs]=(sum[rs]*mul[x])%mod;
val[ls]=(val[ls]*mul[x])%mod,val[rs]=(val[rs]*mul[x])%mod;
mul[ls]=(mul[ls]*mul[x])%mod,mul[rs]=(mul[rs]*mul[x])%mod;
add[ls]=(add[ls]*mul[x])%mod,add[rs]=(add[rs]*mul[x])%mod;
mul[x]=;
}
if(add[x])
{
sum[ls]=(sum[ls]+(sz[ls]%mod*add[x])%mod)%mod;
sum[rs]=(sum[rs]+(sz[rs]%mod*add[x])%mod)%mod;
val[ls]=(val[ls]+add[x])%mod;
val[rs]=(val[rs]+add[x])%mod;
add[ls]=(add[ls]+add[x])%mod;
add[rs]=(add[rs]+add[x])%mod;
add[x]=;
}
if(rv[x])
{
if(ch[x][]) rev(ch[x][]);
if(ch[x][]) rev(ch[x][]);
rv[x]=;
}
#undef ls
#undef rs
}
il void rot(int x)
{
int y=fa[x];int ff=fa[y];int px=idf(x);int py=idf(y);
if(!isroot(y)) ch[ff][py]=x;
fa[x]=ff;con(ch[x][px^],y,px),con(y,x,px^);
pushup(y),pushup(x);
}
void splay(int x)
{
int y=x;stk[++tp]=x;
while(!isroot(y)){stk[++tp]=fa[y],y=fa[y];}
while(tp){pushdown(stk[tp--]);}
while(!isroot(x))
{
y=fa[x];
if(isroot(y)) rot(x);
else if(idf(y)==idf(x)) rot(y),rot(x);
else rot(x),rot(x);
}
}
void access(int x){for(int y=;x;y=x,x=fa[x])splay(x),ch[x][]=y,pushup(x);}
//int findrt(int x){access(x),splay(x);while(ch[x][0])pushdown(x),x=ch[x][0];return x;}
il void mkroot(int x){access(x),splay(x),rev(x);}
il void split(int x,int y){mkroot(x),access(y),splay(y);}
il void link(int x,int y){mkroot(x),access(y),splay(y),fa[x]=y;}
il void cut(int x,int y){split(x,y);fa[x]=ch[y][]=,pushup(y);}
}lct;
int gint()
{
int rett=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){rett=(rett<<)+(rett<<)+c-'';c=getchar();}
return rett*fh;
} int main()
{
n=gint(),m=gint();
int x,y;ui z;char str[];
for(int i=;i<=n;i++)
lct.sz[i]=lct.val[i]=lct.sum[i]=lct.mul[i]=;
for(int i=;i<n;i++)
x=gint(),y=gint(),lct.link(x,y);
for(int i=;i<=m;i++)
{
scanf("%s",str);
if(str[]=='+'){
x=gint(),y=gint(),z=gint();
lct.split(x,y);
lct.sum[y]=(lct.sum[y]+(lct.sz[y]*z)%mod)%mod;
lct.val[y]=(lct.val[y]+z)%mod;
lct.add[y]=(lct.add[y]+z)%mod;
}else if(str[]=='-'){
x=gint(),y=gint(),lct.cut(x,y);
x=gint(),y=gint(),lct.link(x,y);
}else if(str[]=='*'){
x=gint(),y=gint(),z=gint();
lct.split(x,y);
lct.sum[y]=(lct.sum[y]*z)%mod;
lct.val[y]=(lct.val[y]*z)%mod;
lct.mul[y]=(lct.mul[y]*z)%mod;
lct.add[y]=(lct.add[y]*z)%mod;
}else if(str[]=='/'){
x=gint(),y=gint(),lct.split(x,y);
printf("%u\n",lct.sum[y]);
}
}
return ;
}

BZOJ 2631 [国家集训队]Tree II (LCT)的更多相关文章

  1. BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)

    题意 一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和 分析 LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了 CODE #include<bits/s ...

  2. BZOJ 2631 tree | Luogu P1501 [国家集训队]Tree II (LCT 多重标记下放)

    链接:https://www.luogu.org/problemnew/show/P1501 题面: 题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: ...

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

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

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

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

  5. LUOGU P1501 [国家集训队]Tree II (lct)

    传送门 解题思路 \(lct\),比较模板的一道题,路径加和乘的维护标记与线段树\(2\)差不多,然后剩下就没啥了.但调了我将近一下午.. 代码 #include<iostream> #i ...

  6. P1501 [国家集训队]Tree II LCT

    链接 luogu 思路 简单题 代码 #include <bits/stdc++.h> #define ls c[x][0] #define rs c[x][1] using namesp ...

  7. P1501 [国家集训队]Tree II(LCT)

    P1501 [国家集训队]Tree II 看着维护吧2333333 操作和维护区间加.乘线段树挺像的 进行修改操作时不要忘记吧每个点的点权$v[i]$也处理掉 还有就是$51061^2=2607225 ...

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

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

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

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

随机推荐

  1. Netty、NIO、多线程

    一:Netty.NIO.多线程? 时隔很久终于又更新了!之前一直迟迟未动也是因为积累不够,后面比较难下手.过年期间@李林锋hw发布了一个Netty5.0架构剖析和源码解读,看完也是收获不少.前面的文章 ...

  2. vue 上传图片到阿里云(前端直传:不推荐)

    为何要这样做:减轻后端数据库压力(个人觉得于前端没啥用,谁返回来都行) 代码部分: <template> <div class="upLoad"> < ...

  3. ubuntu上的arm-elf-tools -20040427.sh 下载及安装问题的解决

    要完成uclinux在ARM上的移植,必须有这个工具. 下载地址:http://opensrc.sec.samsung.com/download.html 这个网站上还有许多其它资源可以下载.我选择 ...

  4. Python爬虫基础--分布式爬取贝壳网房屋信息(Client)

    1. client_code01 2. client_code02 3. 这个时候运行多个client就可以分布式进行数据爬取.

  5. MVC笔记(一)

    1 MVC介绍 MVC是一个编程思想. 是一种设计模式 思想: 将一个功能分解成3个部分, M: Model (模型) 处理数据相关的逻辑 V: View (视图) 显示页面 C: Controlle ...

  6. 【ACM-ICPC 2018 沈阳赛区网络预赛 I】Lattice's basics in digital electronics

    [链接] 我是链接,点我呀:) [题意] [题解] 每个单词的前缀都不同. 不能更明示了... 裸的字典树. 模拟一下.输出一下就ojbk了. [代码] #include <bits/stdc+ ...

  7. java中File的delete()方法删除文件失败的原因

    java中File的delete()方法删除文件失败的原因 学习了:http://hujinfan.iteye.com/blog/1266387 的确是忘记关闭了: 引用原文膜拜一下: 一般来说 ja ...

  8. iOS动画之美丽的时钟

    1.终于效果图 2.实现思路 在ios中默认是绕着中心点旋转的,由于锚点默认在图层的中点,要想绕着下边中心点转,须要改变图层锚点的位置. 依据锚点.设置position坐标.为时钟的中点. 思考秒针旋 ...

  9. SqlCommand.DeriveParameters failed

    错误信息例如以下: SqlCommand.DeriveParameters failed because the SqlCommand.CommandText property value is an ...

  10. c5

    // // main.c // Switch练习2 // // Created by xiaomage on 15/6/6. // Copyright (c) 2015年 xiaomage. All ...