博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ2631 tree LCT
阅读量:5050 次
发布时间:2019-06-12

本文共 2187 字,大约阅读时间需要 7 分钟。

欢迎访问~原文出处——



题意概括

  一棵n个节点的树,每一个节点有一个权值,m次操作。

  要支持操作有:删边、连边、区间求和、区间加、区间乘。

  保证操作过程中不出现环。

  n,m<=100000


 

题解

  差不多是基础的LCT,加个懒标记。

  2个懒标记,一个是乘的,一个是加的,下传的时候先乘后加。

  注意用无符号的int,用LL会超时。

  (数据较为友善,不卡无符号int)


 

代码

#include 
#include
#include
#include
#include
using namespace std;typedef long long LL;typedef unsigned int U;const int N=100005;const U Mod=51061;int n,m;int fa[N],son[N][2],rev[N];U sum[N],addt[N],addp[N],val[N],size[N];bool isd(char ch){ return '0'<=ch&&ch<='9';}void read(int &x){ char ch=getchar(); x=0; while (!isd(ch)) ch=getchar(); while (isd(ch)) x=x*10+ch-48,ch=getchar();}bool isroot(int x){ return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}void pushup(int x){ if (!x) return; sum[x]=(sum[son[x][0]]+sum[son[x][1]]+val[x])%Mod; size[x]=(size[son[x][0]]+size[son[x][1]]+1)%Mod;}void pushson(int x,U t,U p){ if (!x) return; addt[x]=addt[x]*t%Mod; addp[x]=(addp[x]*t+p)%Mod; val[x]=(val[x]*t+p)%Mod; sum[x]=(sum[x]*t+p*size[x])%Mod;}void pushdown(int x){ if (!x) return; int &ls=son[x][0],&rs=son[x][1]; if (rev[x]){ rev[x]=0; rev[ls]^=1; rev[rs]^=1; swap(ls,rs); } U &t=addt[x],&p=addp[x]; pushson(ls,t,p); pushson(rs,t,p); t=1,p=0;}void pushadd(int x){ if (!x) return; if (!isroot(x)) pushadd(fa[x]); pushdown(x);}int wson(int x){ return son[fa[x]][1]==x;}void rotate(int x){ if (isroot(x)) return; int y=fa[x],z=fa[y],L=wson(x),R=L^1; if (!isroot(y)) son[z][wson(y)]=x; fa[x]=z,fa[y]=x,fa[son[x][R]]=y; son[y][L]=son[x][R],son[x][R]=y; pushup(y); pushup(x);}void splay(int x){ pushadd(x); for (int y=fa[x];!isroot(x);rotate(x),y=fa[x]) if (!isroot(y)) rotate(wson(x)==wson(y)?y:x);}void access(int x){ int t=0; while (x){ splay(x); son[x][1]=t; pushup(x); t=x; x=fa[x]; }}void rever(int x){ access(x); splay(x); rev[x]^=1;}void link(int x,int y){ rever(x); fa[x]=y;}void cut(int x,int y){ rever(x); access(y); splay(y); fa[x]=son[y][0]=0;}int main(){ read(n),read(m); for (int i=1;i<=n;i++){ val[i]=sum[i]=size[i]=addt[i]=1; fa[i]=son[i][0]=son[i][1]=addp[i]=rev[i]=0; } for (int i=1,a,b;i

  

转载于:https://www.cnblogs.com/zhouzhendong/p/BZOJ2631.html

你可能感兴趣的文章
SQLServer 镜像功能完全实现
查看>>
Vue-详解设置路由导航的两种方法
查看>>
一个mysql主从复制的配置案例
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
dvwa网络渗透测试环境的搭建
查看>>
Win8 安装VS2012 和 Sql Server失败问题
查看>>
过点(2,4)作一直线在第一象限与两轴围成三角形,问三角形面积的最小值?...
查看>>
java aes CBC的填充方式发现
查看>>
使用ionic cordova build android --release --prod命令打包报有如下错误及解决方法
查看>>
BZOJ 2338 HNOI2011 数矩形 计算几何
查看>>
关于页面<!DOCTYPE>声明
查看>>
【AS3代码】播放FLV视频流的三步骤!
查看>>
C++标准库vector使用(更新中...)
查看>>
cocos2d-x 2.2.6 之 .xml文件数据读取
查看>>
枚举的使用
查看>>
BZOJ 1531 二进制优化多重背包
查看>>
BZOJ 2324 (有上下界的)费用流
查看>>
python3基础06(随机数的使用)
查看>>
Zookeeper系列(二)特征及应用场景
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>