BZOJ 2631 [国家集训队]Tree II (LCT)
题目大意:给你一棵树,让你维护一个数据结构,支持
边的断,连
树链上所有点点权加上某个值
树链上所有点点权乘上某个值
求树链所有点点权和
(辣鸡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)的更多相关文章
- BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)
题意 一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和 分析 LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了 CODE #include<bits/s ...
- BZOJ 2631 tree | Luogu P1501 [国家集训队]Tree II (LCT 多重标记下放)
链接:https://www.luogu.org/problemnew/show/P1501 题面: 题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: ...
- 洛谷.1501.[国家集训队]Tree II(LCT)
题目链接 日常zz被define里没取模坑 //标记下放同线段树 注意51061^2 > 2147483647,要开unsigned int //*sz[]别忘了.. #include < ...
- 洛谷P1501 [国家集训队]Tree II(LCT)
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u2 v2:将树中原有的 ...
- LUOGU P1501 [国家集训队]Tree II (lct)
传送门 解题思路 \(lct\),比较模板的一道题,路径加和乘的维护标记与线段树\(2\)差不多,然后剩下就没啥了.但调了我将近一下午.. 代码 #include<iostream> #i ...
- P1501 [国家集训队]Tree II LCT
链接 luogu 思路 简单题 代码 #include <bits/stdc++.h> #define ls c[x][0] #define rs c[x][1] using namesp ...
- P1501 [国家集训队]Tree II(LCT)
P1501 [国家集训队]Tree II 看着维护吧2333333 操作和维护区间加.乘线段树挺像的 进行修改操作时不要忘记吧每个点的点权$v[i]$也处理掉 还有就是$51061^2=2607225 ...
- 洛谷 P1501 [国家集训队]Tree II 解题报告
P1501 [国家集训队]Tree II 题目描述 一棵\(n\)个点的树,每个点的初始权值为\(1\).对于这棵树有\(q\)个操作,每个操作为以下四种操作之一: + u v c:将\(u\)到\( ...
- 洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree
[题解] 维护乘法标记和加法标记的LCT #include<cstdio> #include<algorithm> #define Mod (51061) #define N ...
随机推荐
- 工具-docker01
- HDU 1788
必须MARK下:任何时候都要保持清醒头脑,不要被题目绕了.. 其实就是求最小公倍数. #include <iostream> #include <cstdio> #includ ...
- tomcat内存大小设置
tomcat内存大小设置 如果安装为windows服务,需要进行内存设置的时候,选择configure...界面, 在Java Tab页面内可以进行内存参数的设置. 学习了:http://elf884 ...
- Android面试过程描写叙述
1.之前所写项目的介绍 2.android一些常见问题的问答 3.关于android平时非常少用到但实则非常重要的问题描写叙述 技术分析 1自我感觉面试中比較好的方面: 1.熟悉掌握之前所写项目 2. ...
- ListView的adapter中getView方法一直调用
当ListView的高度不定(比如重写ListView搞成可自己主动的扩展的ListView)或 ListView嵌套在SrollView(高度不定)中,listView中的一个item元素改变会使得 ...
- 并发编程网 - ifeve.com
并发编程网 - ifeve.com 让天下没有难学的技术 首页 JAVA 深入浅出ClassLoader 深入浅出ClassLoader Dedicate to Molly. 你真的了解ClassLo ...
- QT使用tableWidget显示双排列表 而且选中用红框圈出来
如需转载请标明出处:http://blog.csdn.net/itas109 整个project下载地址:http://download.csdn.net/detail/itas109/7607735 ...
- openssl之BIO系列之24---SSL类型的BIO
SSL类型的BIO ---依据openssl doc\crypto\bio_f_ssl.pod翻译和自己的理解写成 (作者:DragonKing, Mail: wzhah@263.net ,公布于:h ...
- chrome设置书签默认显示
实用的设置! 这样已设置,就可以方便的查看一些常用的书签了!
- 2017-3-5 leetcode 442 531 533
今天莫名其妙睡到了中午,很难受... leetcode442 https://leetcode.com/problems/find-all-duplicates-in-an-array/?tab=De ...