[bzoj2631]tree_LCT
tree bzoj-2631
题目大意:给定一个n个点的树,每个点的初始权值为1,支持:删边加边(这两个操作同时进行,保证操作之后还是一棵树),路径加,路径乘,查询路径和。
注释:$1\le n,q\le 10^5$,$1\le c \le 10^4$。
想法:暴力给的很优雅:15‘没有加边删边且保证是链,我们直接用线段树维护。50'没有加边删边,我们裸上树剖+线段树。满分的话我们用LCT维护加边删边。
具体地:我的习惯是先×后+,所以每一次乘法都先将加法标记也进行修改。询问的话直接makeroot,我们节点信息直接维护原树子树信息,然后对应的查询就是链上的信息。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 100050
#define mod 51061
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
typedef unsigned int ui;
int n,m,ch[N][2],f[N],rev[N];
ui sum[N],mul[N],add[N],siz[N],val[N];
char opt[10];
inline bool isrt(int x)
{
return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;
}
void pushdown(int p)
{
if(mul[p]!=1)
{
ui u=mul[p];
sum[ls]=sum[ls]*u%mod; mul[ls]=mul[ls]*u%mod; add[ls]=add[ls]*u%mod; val[ls]=val[ls]*u%mod;
sum[rs]=sum[rs]*u%mod; mul[rs]=mul[rs]*u%mod; add[rs]=add[rs]*u%mod; val[rs]=val[rs]*u%mod;
mul[p]=1;
}
if(add[p])
{
ui d=add[p];
sum[ls]=(sum[ls]+siz[ls]*d%mod)%mod; add[ls]=(add[ls]+d)%mod; val[ls]=(val[ls]+d)%mod;
sum[rs]=(sum[rs]+siz[rs]*d%mod)%mod; add[rs]=(add[rs]+d)%mod; val[rs]=(val[rs]+d)%mod;
add[p]=0;
}
if(rev[p])
{
swap(ch[ls][0],ch[ls][1]);
swap(ch[rs][0],ch[rs][1]);
rev[ls]^=1; rev[rs]^=1;
rev[p]=0;
}
}
void pushup(int p)
{
siz[p]=siz[ls]+siz[rs]+1;
sum[p]=(sum[ls]+sum[rs]+val[p])%mod;
}
void update(int p)
{
if(!isrt(p)) update(f[p]);
pushdown(p);
}
void rotate(int x)
{
int y=f[x],z=f[y],k=get(x);
if(!isrt(y)) ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
pushup(y); pushup(x);
}
void splay(int x)
{
update(x);
for(int fa;fa=f[x],!isrt(x);rotate(x))
if(!isrt(fa))
rotate(get(fa)==get(x)?fa:x);
}
void access(int p)
{
int t=0;
while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
}
void makeroot(int p)
{
access(p); splay(p); swap(ls,rs); rev[p]^=1;
}
void link(int x,int p)
{
makeroot(x); f[x]=p;
}
void cut(int x,int p)
{
makeroot(x); access(p); splay(p); ls=f[x]=0;
}
void split(int x,int p)
{
makeroot(x); access(p); splay(p);
}
int main()
{
scanf("%d%d",&n,&m);
int i,x,y,z,w;
for(i=1;i<=n;i++) val[i]=mul[i]=siz[i]=sum[i]=1;
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y); link(x,y);
}
for(i=1;i<=m;i++)
{
scanf("%s%d%d",opt,&x,&y);
int p=y;
if(opt[0]=='+')
{
scanf("%d",&z); split(x,p);
sum[p]=(sum[p]+siz[p]*z%mod)%mod;
val[p]=(val[p]+z)%mod;
add[p]=(add[p]+z)%mod;
}
else if(opt[0]=='-')
{
scanf("%d%d",&z,&w); cut(x,y); link(z,w);
}
else if(opt[0]=='*')
{
scanf("%d",&z); split(x,p);
sum[p]=sum[p]*z%mod;
val[p]=val[p]*z%mod;
add[p]=add[p]*z%mod;
mul[p]=mul[p]*z%mod;
}
else
{
split(x,p); printf("%u\n",sum[p]);
}
}
}
小结:LCT是个好东西。
[bzoj2631]tree_LCT的更多相关文章
- bzoj2631 3282
这两题都是link cut tree的裸题之前看Qtree的论文,只会在确定父子关系的情况下连边和删边如果在任意两个点连边删边怎么做呢?这时候我们不能随意的将一个点的父节点设为另一个点,因为其中某个点 ...
- bzoj2631: tree
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ2631——tree
1.题目大意:bzoj1798的lct版本 2.分析:这个把线段树改成splay就好 #include <stack> #include <cstdio> #include & ...
- 【bzoj2631】tree link-cut-tree
2016-06-01 08:50:36 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2631 注意加和乘的标记下传问题. 还有就是split后 ...
- bzoj2631: tree lct
要打mul和add的lct 50000+的mod用unsigned int好了TAT (坑爹没打pc('\n');(静态)调了好久,样例竟然只输出一个,orz,也不提示PE T_T) #include ...
- LCT模板(BZOJ2631)
用LCT实现路径加,路径乘,断开及加上一条边(保证是树),查询路径和. #include <cstdio> #include <algorithm> #define l(x) ...
- 【BZOJ2631】tree
Description 一棵n个点的树.每一个点的初始权值为1. 对于这棵树有q个操作,每一个操作为下面四种操作之中的一个: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 ...
- bzoj2631
题解: lct+链上修改 每一次修改的时候记录lazy标记 如果有了乘法,加法的lazy标记也要相应的随之变化 代码: #pragma GCC optimize(2) #include<bits ...
- 【bzoj2631】tree LCT
题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一:+ u v c:将u到v的路径上的点的权值都加上自然数c:- u1 v1 u2 v2:将树中原有的边( ...
随机推荐
- codeforce1046 Bubble Cup 11 - Finals 题解
比赛的时候开G开了3h结果rose说一句那唯一一个AC的是羊的心态就崩了.. 这套题感觉质量挺好然后就back了下 A: AI robots 有三个限制条件:相互能够看见和智商的差.使用主席树,可以维 ...
- bzoj5192: [Usaco2018 Feb]New Barns
不想写看zory大佬 #include<cstdio> #include<iostream> #include<cstring> #include<cstdl ...
- hibernate初步2
Hibernate级联设计 数据库表之间的关系(主要关系有一对多.一对一.多对多)主要是从如下三个方面体现出来: 1.表体设计 2.实体类的设计 3.配置文件 以下是一些重要级联设计参数属性介绍: c ...
- python chunk 方式读取大文件——本质上还是file read自身支持
参考:https://stackoverflow.com/questions/519633/lazy-method-for-reading-big-file-in-python 最优雅方式: file ...
- K-means algorithm----PRML读书笔记
The K-means algorithm is based on the use of squared Euclidean distance as the measure of dissimila ...
- CentOs7 修改rpm安装背景图
http://bbs.chinaunix.net/thread-4166176-1-1.html
- PCB MongoDB数据库 备份与还原
一. MongoDB数据库 备份与还原工具介绍: 数据备份工具 mongodump.exe 数据还原工具 mongorestore.exe 二. MongoDB数据库备份 mongodump - ...
- Oracle创建用户教程
计算机-->管理-->应用程序与服务-->(OracleOraDb11g_home1TNSListener 和 OracleServiceORCL 服务)->启动服务 打开Or ...
- java 实现将java对象转为yaml文件
首先我们建两个类,以下两个类展示的是一个学生拥有多个手机号码联系人. 先是学生类: package com.ming.yaml.beans; import java.util.ArrayList; i ...
- Asp.net MVC4 Step by Step (1)-路由,控制器,视图
注意:此文需要你有一定Asp.net MVC的基础,很多东西省略了,只是做个提要笔记形式. 要创建一个ASP.NET MVC的Web应用,首先要去下载ASP.NET MVC框架, 可以访问ASP.NE ...