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

边的断,连

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

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

求树链所有点点权和

(辣鸡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. html中的meta标签属性

    <!-- 声明文档使用的字符编码 --> <meta charset='utf-8'> <!-- 优先使用 IE 最新版本和 Chrome --> <meta ...

  2. HDU 5279 YJC plays Minecraft (分治NTT优化DP)

    题目传送门 题目大意:有$n$个小岛,每个小岛上有$a_{i}$个城市,同一个小岛上的城市互相连接形成一个完全图,第$i$个小岛的第$a_{i}$个城市和第$i+1$个小岛的第$1$个城市连接,特别地 ...

  3. CentOS6.8安装

        VMware下CentOS 6.8安装配置 简述 Linux的安装方法有很多种,下面,我们主要以镜像安装为例,介绍CentOS的安装过程及相关的参数设置,详细步骤如下. CentOS安装配置 ...

  4. Linux 获取帮助

    Linux中获取帮助的方法  方法:    COMMAND --help 或者 help COMMAND    whatis    man或info    本地帮助文档 /usr/share/doc/ ...

  5. Django入门--自定义过滤器与标签

    ---恢复内容开始--- 为了让Django找到自定义的模板过滤器和模板标签,需要进行文件路径配置,配置方式分为APP目录下配置和项目路径下配置两种方式: 1.在APP目录下配置:针对某个应用特定的自 ...

  6. 干货:鲜为人用的MySQL高级特性与玩法!

    上一篇文章<万字总结:学习MySQL优化原理,这一篇就够了!>文末给大家留有两个开放的问题: 有非常多的程序员在分享时都会抛出这样一个观点:尽可能不要使用存储过程,存储过程非常不容易维护, ...

  7. add Admob with Cocos2d-x on iOS

    add Admob with Cocos2d-x on iOS (2013-02-27 14:12:00) 转载▼ 标签: c=blog&q=it&by=tag" targe ...

  8. 剑指Offer面试题33(java版):把数组排成最小的数

    题目:输入一个正整数数组.把数组里面全部的数字拼接排成一个数,打印能拼接出的全部数字中的一个.比如输入数组{3,32.321}.则打印出这3个数字能排成的最小数字321323. 这个题目最直接的做法应 ...

  9. IOS-2-C语言和Objective-C语言衔接学习资料

    前言:在IOS学习中.通常会先学习一周的C语言,两周的Objective-C语言,这是今后开发的最基础最重要的部分,以下给大家分享一下培训课上的精简资料: C语言和Objective-C语言衔接学习资 ...

  10. 升级Xcode 导致插件失效的解决的方法

    我们在升级xcode的情况下,我们的一些第三方插件就会失效. 比方cocoapods,等比較重要的三方插件, 解决这个问题例如以下: 进入插件文件夹:~/Library/Application Sup ...